aboutsummaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
authorKaran Jayachandra <mail@karanjayachandra.com>2026-07-26 19:13:32 +0200
committerKaran Jayachandra <mail@karanjayachandra.com>2026-07-26 19:13:32 +0200
commitd263d7c4ff0397fa421802446e00badf69bd44e5 (patch)
treee7353a754f459754ed45b55c22e9695f656fe2aa /README.md
parenta092b9462094afc74798466a9d6fef53ff3d17d3 (diff)
Added the changes for automatic deploy
Diffstat (limited to 'README.md')
-rw-r--r--README.md24
1 files changed, 19 insertions, 5 deletions
diff --git a/README.md b/README.md
index cc24110..c0c887a 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,26 @@
# goodall
-Docker Compose media stack (Jellyfin, Radarr, Sonarr, Prowlarr, Bazarr, qBittorrent) fronted by Caddy, reachable only over Tailscale.
+Docker Compose media stack (Jellyfin, Radarr, Sonarr, Prowlarr, Bazarr, qBittorrent) fronted by Caddy, reachable only over Tailscale. qBittorrent's traffic is routed entirely through Gluetun (WireGuard to Mullvad) via `network_mode: "service:gluetun"`.
-Deployed on the NAS at `/volume2/docker/goodall` (host `karan@100.121.200.111`, tailnet name `goodall.taildc6b0a.ts.net`). This local directory is the source of truth for edits; redeploy a changed file with:
+Deployed on the NAS at `/volume2/docker/goodall` (host `karan@100.121.200.111`, tailnet name `goodall.taildc6b0a.ts.net`). This local directory is the source of truth for edits; ship a full deploy with:
```
-ssh karan@100.121.200.111 "cat > /volume2/docker/goodall/<file>" < ./<file>
-ssh karan@100.121.200.111 "cd /volume2/docker/goodall && sudo docker compose up -d"
+./deploy.sh
```
-See [MIGRATION_STATUS.md](MIGRATION_STATUS.md) for current deployment status and remaining work.
+This clears the project directory on the NAS (preserving `config/` runtime state and `.env`), streams the repo over via tar+SSH (DSM's bundled rsync only supports its own daemon/module mode, not plain SSH+path, so this project uses tar instead), decrypts `.env.enc` and writes it directly to the NAS, then runs `docker compose pull && up -d` remotely.
+
+Note: this NAS's Docker Manager GUI doesn't show `goodall` as a project since it was deployed via SSH/CLI rather than the GUI's own wizard — cosmetic only, the stack runs fine either way.
+
+## Secrets
+
+All secrets and per-deployment config (VPN credentials, Gandi DNS token, LAN/Tailscale IPs, PUID/PGID/TZ, media paths, and the four app API keys) live encrypted in `.env.enc`, via sops. To view: `sops -d --input-type dotenv --output-type dotenv .env.enc`. To edit: `sops --input-type dotenv --output-type dotenv .env.enc` (opens `$EDITOR` on the decrypted content, re-encrypts on save). `deploy.sh` decrypts this on every run and writes it to the NAS directly — there's no plaintext `.env` to hand-maintain locally.
+
+## Updates
+
+All images (including Gluetun) track `:latest`. Nothing auto-updates — re-run `./deploy.sh` to pull and recreate everything. This is deliberate: `gluetun` and `qbittorrent` share a network namespace (`network_mode: "service:gluetun"`), so updates need to recreate both together, which a project-level `docker compose pull && up -d` does correctly and a per-container auto-updater would not.
+
+## Gotchas
+
+- **Gluetun blocks inbound container-to-container traffic by default** — `FIREWALL_INPUT_PORTS=8123` in `docker-compose.yml` is required, or qBittorrent's WebUI (proxied by Caddy for `dl.karanj.com`) returns a 502.
+- **Caddy's Gandi DNS-01 challenge needs `propagation_timeout -1`** in the `tls_gandi` snippet (`caddy/Caddyfile`) — Gandi's own nameserver propagation is inconsistent across resolvers, so Caddy's own pre-check needs to be skipped and left to Let's Encrypt to validate directly.