← Homelab

De diensten in mijn homelab: Docker, media, wachtwoorden en een database-cluster

Wat er draait en waarom zo: Docker Compose per stack in Git, een mediastack met hardware-transcoding, Passbolt als wachtwoordmanager, een eigen cloud- en fotodienst, en PostgreSQL met Patroni en een echte witness.

Docker als basis

De meeste diensten draaien in Docker Compose, met één stack per map en de compose-bestanden in Git. Een paar spelregels:

  • Wat lokaal gefixt wordt, gaat Git in. Een fix op een host die niet gecommit wordt, is bij de volgende deploy weg. Ik heb een keer een stack aangetroffen met weken aan niet-gecommitte wijzigingen; sindsdien controleer ik dat bij elke deploy.
  • Images pinnen en scannen. Bij voorkeur een vaste versie, en bij eigen builds een Trivy-scan.
  • Beheerinterfaces alleen vanaf het thuisnetwerk. De reverse proxy laat ze alleen toe voor het lokale netwerk.
  • Monitoring per container met cAdvisor, met de juiste vlaggen. Zie Hoe cAdvisor mijn lokale LLM vier keer zo traag maakte.
  • GPU in containers met device-cgroup-regels in de spec, zodat een kernel-update ze niet wist. Zie De GPU die na elke kernel-update verdween.

Mediastack

Jellyfin, met de downloadtools eromheen, op dezelfde VM als de AI, want ze delen de RTX 3060.

  • Hardware-transcoding met NVENC, en hardware-decoding voor H.264, HEVC, VC-1, MPEG-2, VP9 en AV1. Een transcode kost ~150 MiB VRAM per stream, dus het past naast het taalmodel.
  • De bibliotheek staat op de Pi-edge en komt via NFS binnen.
  • Een les bij het meten: Jellyfin meldt "Transcoding" ook als alleen het geluid wordt omgezet en het beeld direct wordt doorgegeven. Kijk naar -codec:v:0 in de ffmpeg-commandline voordat je concludeert dat de GPU het druk heeft. Het CPU-percentage van ffmpeg zegt ook weinig: een grote probesize via NFS verklaart al de helft.

Passbolt

Passbolt is de wachtwoordmanager van het huishouden: zelf gehost, met end-to-end encryptie op basis van OpenPGP. Het draait in Docker achter de reverse proxy.

Bij het php2shell-lek kreeg Passbolt als een van de eerste de tussenmaatregel (session.upload_progress uit en strikte sessies). Gevolg: actieve sessies werden uitgelogd, de accounts zelf bleven intact. Dat was te verwachten, en de moeite waard.

Cloud en foto's

  • Een eigen cloudomgeving voor bestanden en agenda's, native geïnstalleerd, met de data buiten de webroot. Bij de laatste update faalde de ingebouwde updater op een certificaatfout bij de leverancier zelf; handmatig bijgewerkt via de officiële tarball, met de oude installatie als vangnet.
  • Een eigen fotodienst voor de telefoonback-ups.
  • Geen gedeelde Redis tussen diensten. Het is verleidelijk één Redis voor alles te gebruiken, maar dan kunnen sleutels botsen en hangen diensten aan elkaar vast. Elke dienst krijgt een eigen, lokale cache.

PostgreSQL met Patroni

Diensten die een database nodig hebben, waaronder de kennisbank van de AI met pgvector, gebruiken een PostgreSQL-cluster met Patroni op twee nodes en een aparte witness-VM als derde etcd-lid.

  • Waarom een witness: met twee nodes heb je geen meerderheid als er één wegvalt. Het derde etcd-lid geeft het quorum.
  • Waarom niet op de Pi: etcd heeft een lage fsync-latency nodig. Op een Pi met USB-schijven, die ook de mediabibliotheek serveert, kan één filmavond met veel I/O etcd zo vertragen dat de leider zijn lease verliest. Dan gaat het cluster in read-only.
  • Klein maar compleet: de witness heeft een paar honderd MB nodig. Een kleine VM op de hypervisor is goedkoper dan een storing.

Op het werk ben ik dezelfde combinatie in productie tegengekomen, met een les over systemd. Zie Eén OOM-kill, en Patroni ging mee.

Wat dit allemaal verbindt

Elke dienst achter dezelfde reverse proxy, met dezelfde monitoring, in dezelfde Git en met dezelfde regels. Dat maakt een homelab met een dozijn diensten beheersbaar voor één persoon.