All projects

Infrastructure · 2024 – present Project 4 of 20

Home server

Websites, mail, media and local AI on one machine – all of it in NixOS configuration.

At a glance

Role
Design, administration and operations
Period
2024 – present
Status
Live
Technologies
10 technologies

I have been running the server myself since 2024. One physical machine hosts websites for me and for clients, a mail server, a media library, game servers, a streaming studio and a local language model. The whole system is described in a NixOS configuration split into modules, so I build every change first, compare it with the running system and only then deploy it. If something goes wrong, I roll back to the previous generation.

Why it is technically interesting

  • Websites from a list. More than 30 nginx virtual hosts with PHP-FPM are generated from a list in the configuration, so shared security rules apply to all of them at once. Let's Encrypt certificates are issued over HTTP-01, and internal services share a wildcard certificate issued over DNS-01.
  • Internal services run on their own addresses, which nginx by default serves only to the home network and over Tailscale.
  • Local AI. Ollama in Docker with the qwen2.5:7b model running entirely on a GTX 1060 graphics card. The service listens on localhost only and is used by AniMood, among others.
  • A streaming studio without a monitor. OBS runs on the server itself on a virtual display, receives the picture from the gaming PC over NDI, encodes it on the graphics card (NVENC) and is controlled over VNC from the home network.
  • Docker for the Mailu mail server with spam filtering and DKIM signing, Strapi and other applications.
  • Game servers as NixOS modules; the newest one runs as an isolated service with its own user and a memory limit.
  • Media and monitoring. Plex with its library on a ZFS pool; Prometheus with node exporter collects metrics and Grafana shows them.

Obstacles and how I solved them

  • A graphics card dropped by the new driver. NixOS 26.05 moved to an NVIDIA driver that no longer supports the Pascal generation, and the GTX 1060 disappeared. The configuration now explicitly picks the older 580 branch, which still supports the card.
  • The GPU in containers. Docker's original NVIDIA switch is deprecated and --gpus all fails on Docker 29. The graphics card is passed to containers through CDI instead.
  • OBS without hardware encoding. OBS on NixOS could not find the NVENC library and offered only software x264; adding the driver path to its environment fixed it. The NDI plugin would not build either, because the vendor publishes new SDKs at the same address and the checksum in the package stopped matching – the configuration overrides it with the real one.
  • A data pool that did not mount after a reboot. The ZFS pool was missing from the import cache, so after a reboot its mount point stayed empty on the system disk, and the services that manage the library started filling it again. The pool is now imported declaratively. The usual fileSystems entry, on the other hand, would drop the boot into emergency mode – which is documented in the configuration too.

What you don't see

  • Backups with a test restore. The databases of AniMood and of this website are backed up every night with an online SQLite backup, followed by an integrity check, zstd compression, unpacking the finished archive and a second check. Backups are kept for 30 days.
  • Jobs with minimal rights. Backups and imports run as systemd services under the website's user, with a read-only system and no way to gain more privileges. The production database is never opened as root – SQLite would create helper files with the wrong owner and the website would stop writing.
  • A shared baseline for every site. The server serves no hidden files, and for sites with files on disk no databases, logs, configuration or backups either.
  • Changes with reasons. The configuration explains why wherever a solution is unusual, so it still makes sense months later.

Technology

  • NixOS 26.05 – declarative configuration in modules and a rollback to the previous generation with one command.
  • nginx, PHP-FPM and Let's Encrypt – websites, reverse proxies and automatic certificates.
  • Docker with CDI – containerised services, including access to the graphics card.
  • Mailu – my own mail server.
  • Tailscale – access to internal services away from home.
  • ZFS – the data pool for media.
  • Ollama on an NVIDIA GTX 1060 – a local language model.
  • OBS, NDI and NVENC – streaming.
  • Prometheus and Grafana – server metrics.

Built with

  • NixOS
  • Docker
  • nginx
  • Ollama
  • ZFS
  • PHP-FPM
  • Tailscale
  • Mailu
  • Prometheus
  • Grafana

Keyboard shortcuts.

Keyboard shortcuts for this site. They stay quiet while you type into a form.

This site

?
This help
g
12-column grid, components and page metrics
d
Appearance: system, light, dark, Linkin Park
Ctrl P
Print the CV instead of the website
Esc
Close the dialog or the grid

The blue dot after the name can be grabbed and thrown.

Linkin Park

l setlist lp
The setlist, songs by album
papercut
The page tears like paper
numb
The site goes numb for a few seconds
faint
The page faints and comes round
meteora
A meteor shower and a direct hit on the dot after the name
fromzero emily
The site fades down to zero and is reborn, with thanks to Emily Armstrong
concert koncert
Concert: the site runs through the colours of every album
castleofglass
The page turns to glass, cracks and shatters
iridescent
Headings and dots shimmer in rainbow colours
breakingthehabit
Whatever is on screen falls apart and snaps back
intheend
End credits, like at the cinema
victim morethevictim
The site breaks up in a glitch and stays distorted (until a reload, another word or Esc)
finalmasquerade
A masquerade mask over the whole site, the camera flies through an eye
lost
Off to the 404 page

Type the words anywhere outside the form; case and spaces do not matter. With reduced motion you get a short note instead.

On a phone, five taps on the blue dot after the name open the setlist.