# homelab-compose
The docker-compose stack and support scripts that run on the single NUC
sitting under my desk. Media, photos, documents, DNS, git, metrics. One
Caddy in front doing TLS.
This repo is opinionated and not generic. Read it, copy what makes sense,
don't `git clone && up -d`.
## Layout
docker-compose.yml all the services
Caddyfile reverse proxy
scripts/backup.sh daily cron: rsync -> local snapshot -> B2
scripts/restore.sh pull one snapshot back from B2
scripts/health-check.sh curl each service, alert on non-200
.env.example copy to .env and fill in
## First run
cp .env.example .env
$EDITOR .env
docker compose up -d
Caddy grabs TLS certs from your internal CA on start. I use step-ca with
a local root; adjust `tls` directives if you use ACME.
## Updating
I don't auto-update. Every Sunday morning I run:
docker compose pull
docker compose up -d
...and read the changelogs for anything that got a minor bump. Paperless
and Immich have been the noisy ones.
## Backups
`scripts/backup.sh` is wired into cron at 03:15 every night:
15 3 * * * /srv/homelab/scripts/backup.sh >> /var/log/homelab-backup.log 2>&1
It snapshots `/srv/data` with rsync --link-dest, then rclones the newest
snapshot to Backblaze B2. Retention: 30 daily + 12 monthly local, same on
B2. Test restore quarterly with `scripts/restore.sh --dry-run`.
## Health check
`scripts/health-check.sh` runs from cron every 5 minutes and hits each
service's health endpoint. Exit 0 = all good, 1 = one service failed, 2 =
multiple. Cron mails me on non-zero.
## Services
- jellyfin media server, hardware-transcode via /dev/dri
- immich photos, needs a postgres and redis next to it
- paperless OCR document archive
- gitea git, for the stuff I don't put on mercemay.top/src/
- syncthing laptop<->NUC folder sync
- pihole DNS + blocklist
- prometheus scrapes node + blackbox exporters
- grafana dashboards
## License
Unlicense. See `LICENSE`. The config is obvious once you see it.