PRJ-01
media-server-iac
Infrastructure-as-code for a self-hosted media stack. One compose file, nine services, pinned images, CI validation and automated update PRs.
Self-hosted media stack (VPN, download client, the *arr suite, request front end, Plex) as a declarative deployment. The running host is reproducible from the repository plus one uncommitted .env.
A single compose file defines all nine services, their shared bridge network and every variable the stack consumes. Nothing runs latest: each image is pinned to an exact version, so host state always corresponds to a commit. Renovate raises a pull request when an upstream release appears; CI validates the compose file, lints YAML and shell, and secret-scans every push. Applying an update is git pull && make update on the host, and rollback is a revert.
The VPN kill-switch is structural rather than rule-based. qBittorrent runs inside the Gluetun container’s network namespace (network_mode: "service:gluetun"), so it has no network interface of its own: if the tunnel drops there is no route out. Compose health-check gating means the download client never starts before the tunnel is up.
Second iteration of the project. The first version generated a compose-per-service layout from a YAML parameter file with Bash handling deployment order and service wiring; the rewrite traded generation for a single readable definition, and script-driven updates for reviewable PRs.