Skip to content

torrentvpn stack — 36 containers from one compose file, plus one that is not

~/torrentvpn/docker-compose.yml (34 services) + .env. Every service's config lives in ~/torrentvpn/<service>/. samba-nas is not from compose — it was docker run and the compose samba service has drifted from it.

Why this shape

One stack dir so one backup script (docker-backup.sh) and one rescue archive cover everything. VPN isolation is by network namespace: qBittorrent runs inside gluetun's, so torrent traffic cannot leave except through the tunnel.

Shape

Services by group (compose line numbers, 09-08): - VPN + downloads: gluetun:2 (NordVPN; qbittorrent:40 uses network_mode: service:gluetun), unpackerr:58, rar-extractor:636, prowlarr:184, flaresolverr:265 - Media: plex:93 (/mnt/storage/{movies,tv,anime,kids-*}), jellyfin:280 (/mnt/storage:/data:ro), tautulli:557, tdarr:572 + tdarr-node:592 (no libraries configured — item 16 note), bazarr:212, overseerr:125 - *arr: radarr:139, sonarr:154, sonarr-anime:169, recyclarr:198 - Photos: immich-server:456, immich-machine-learning:481, immich-postgres:438, immich-redis:451 → immich - Network: pihole:357 (dns.lan, resolves *.lan), npm:527 (npm.lan:81, proxies *.lan), wg-easy:327 (wg.lan; wg-docker-watchdog.timer restarts it every minute if stopped), duckdns:542 - Secrets: vaultwarden (end of file; vault.embeddedera.com via NPM, HTTPS only) → vaultwarden - MRP/inventory: inventree-db/cache/server/worker/proxy (end of file; erp.lan via NPM, LAN-only for now) → inventree - Ops: homer:381 (dashboard; vpn-check writes its VPN tile), portainer:503, uptime-kuma:514, dozzle:427, glances:411, scrutiny:690, filebrowser:393 (files.lan, /mnt/storage as /srv/media), mosquitto:674 - samba:615 — ghost. Binds /mnt/storage/Storage-snapshots; the live samba-nas binds /mnt/disk1/Storage-snapshots and serves EmbeddedEra. docker compose up -d would recreate it wrong.

Rules: - Never a bare docker compose up -d. Always name the service: docker compose up -d scrutiny. Stop/start samba-nas by name with docker stop/start. - Recreate gluetun and qbittorrent together or qbittorrent loses its network. - gluetun's ICMP health probe fails forever on NordVPN; gf fixes it (HEALTH_TARGET is the wrong variable name on this build). - Radarr/Sonarr/Sonarr-anime: removeCompletedDownloads=false and removeFailedDownloads=falsethis is the safety interlock that prevents the 09-03 incident. DBs backed up as *.db.bak.incident-20260903. - .env is 0600; the only off-box copy is env.gpg on the rescue USB.

Leftovers in the dir: 12 docker-compose.yml.bak* copies, prowlarr-broken-2025* ×4, immich-backup-20251205-*, snapraid-webui/, h5ai/, homeassistant/, jellystat/, openvpn/ — config dirs with no running container.

Connected to

If you change this

  • Hits: docker-backup.sh snapshot contents (skips Videos media immich wireguard-wg_confs docker-backups + caches) · the rescue archive · Pi-hole/NPM entries if a hostname changes · homer config.yml links · the *arr interlock if you touch a download client.
  • Does not hit: SnapRAID, mergerfs, rsnapshot, precious.

Surfaces

Surface Role
dps alias docker ps table
Portainer (portainer.lan), Dozzle (logs) UI
docker-backup.sh 01:00 rsync of config dirs → /mnt/storage/docker-backups/snapshots/ (7 kept); log /var/log/docker-backup.log (832 MB, unrotated)

See

  • Source: /home/angel/torrentvpn/docker-compose.yml · /usr/local/bin/docker-backup.sh · ~/.local/bin/gf