For a long time my homelab was a pile of services each installed the way its README suggested, which is to say no two the same. One was a package, one was a tarball in /opt, one was running out of a screen session I was frankly scared to detach from. Every upgrade was an adventure, and "what's actually running on this box" was a question I couldn't answer without ssh-ing in and grepping ps.
So over a weekend I moved the lot to a single docker-compose.yml. Not Kubernetes, not Swarm, nothing clever. One file, one host, one docker-compose up -d, and now I can read the entire state of the house off a screen.
The shape of it is dull, which is the compliment. Each service is a block, each gets a named volume for its data, and they share a network so they can find each other by name.
version: "3"
services:
sonarr:
image: linuxserver/sonarr
restart: unless-stopped
volumes:
- sonarr_config:/config
- /tank/media:/media
ports:
- "8989:8989"
transmission:
image: linuxserver/transmission
restart: unless-stopped
volumes:
- transmission_config:/config
- /tank/downloads:/downloads
ports:
- "9091:9091"
volumes:
sonarr_config:
transmission_config:
The restart: unless-stopped line is doing a lot of quiet work: when the box reboots, everything comes back, in order, without me. That alone fixed the recurring Sunday-evening ritual of remembering which six things needed starting by hand.
The real win is that the config is now a file I can read, version, and back up. It lives in a git repo. If the host dies entirely, recovery is: install Docker, clone the repo, restore the volumes, up -d. I've not had to do that in anger yet, but knowing the whole house is one file and a volume backup away from rebuildable is the most relaxed I've ever been about my own infrastructure. The bus factor used to be "whatever I could remember". Now it's a file.