Ramblings of an aging IT geek
← Ramblings of an aging IT geek
homelab

one compose file to run the house

Consolidating the homelab's scattered containers into a single Docker Compose stack, and the trade-offs of putting everything in one file.

A small server rack

For about a year my homelab was a pile of docker run commands I'd typed once and prayed I'd never have to type again. They lived in my shell history and in a text file that was already out of date. When the box rebooted last weekend, half of them didn't come back, and I spent an hour reconstructing flags from memory. That was the push I needed to move everything into a single docker-compose.yml.

why one file

You could argue for one Compose file per service, and there's a real case for it: blast radius, independent restarts, cleaner separation. I went the other way and put the lot in one file, because the honest truth is this is a house, not a datacentre. I want docker-compose up -d to bring back the entire stack after a reboot, and I want to read the whole topology on one screen.

What's in it: a reverse proxy, DNS, a couple of dashboards, the usual media bits, and a small Postgres that two of them share. Roughly nine services. That's about the limit of what reads comfortably in one file before you want to start splitting things.

version: "3"

services:
  proxy:
    image: traefik:1.2
    command: --docker
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik.toml:/traefik.toml
    restart: unless-stopped

A homelab rack with cabling

the bits that bit me

restart: unless-stopped on everything was the single most valuable change. That's what gets the stack back after a reboot without me touching it, which was the original sin I was trying to fix.

Volumes are where I lost the most time. I'd been letting Docker manage anonymous volumes, which is fine right up until you want to know where your data actually lives. I moved everything to bind mounts under one directory so I can back it up with a single rsync. Named volumes are tidier; bind mounts are honest about where the bytes are, and for a homelab I'll take honest.

The networking caught me too. By default Compose puts everything on one project network and lets services find each other by name, which is exactly what I wanted, so the proxy can reach dashboard without me hardcoding IPs. Once I stopped fighting that and leaned into it, half my config disappeared.

It's not elegant and a purist would split it up. But it boots clean, it fits on a screen, and the whole house came back on its own after I pulled the plug to test. Good enough is a real engineering target, and this clears it.