FrankBook-Pro becomes the only *arr/qBittorrent deployment. Every fleet
container (qB + five arrs) now shares gluetun's netns, so all egress —
torrent, indexer APIs, metadata lookups — exits the WireGuard tunnel by
construction (AllowedIPs=0.0.0.0/0); the arrs' own ports publish on the
gluetun unit, none on the arr units themselves.
- dankserver/compose.yaml: remove the six arr services (the Aug 20 compose
copy — never healthy, superseded; config dirs trashed on the host)
- dankclaw/Caddyfile + shared/homepage/services.json: arr vhosts and
probes repoint 192.168.0.235 -> 192.168.0.112 (FrankBook-Pro)
- frankbook-pro units: five arrs join gluetun netns (Wants/After/Network);
gluetun publishes 9696/8989/7878/8686/8787 alongside 8080/6881
- tests/frankbook_quadlet.bats: new VPN egress seam — every arr+qB unit
must share gluetun's netns and publish no port; gluetun must publish the
whole fleet's ports
- deploy-plan.py: gluetun changes carry the whole netns family (a gluetun
recreation kills all six joiners); dankserver compose set loses the arrs
- AGENTS.md: deployment is complete only when unit tests AND the Playwright
E2E suite both pass
Per user direction, Caddy runs only on dankclaw. It fronts every
service on both hosts: local services by container name, quadlet
services by published LAN port, dankserver services by published LAN
port (192.168.0.235:PORT).
- dankclaw/Caddyfile: merged vhost list (was: two Caddyfiles, one per
host). gitea's single vhost moves in from the retired gitea-caddy
quadlet (option B). Upstreams fixed to live reality: gitea :3000,
search :8081 (gluetun), chat :3005 (open-webui quadlet), media
services via 192.168.0.235. Retired: llms (open-webui on dankserver
is removed; chat is its successor), the dankserver homepage (302 to
the shared one).
- dankserver/Caddyfile, dankclaw/gitea/Caddyfile: deleted (git rm).
- dnsmasq addn-hosts: every name -> 192.168.0.143 (the one Caddy
host); no .235 records, no llms.
- compose.yaml: removed the openwebui/postgres/gitea services (they
are quadlets now); caddy service mounts the rendered Caddyfile from
/home/dank/Containers/caddy, healthcheck probes the bare-IP
catch-all (302).
- deploy.sh: per-target logic (dankserver = pull-only, health via the
shared Caddy at 192.168.0.143); renders CADDY_BASICAUTH_HASH from
the host .env into the mounted Caddyfile.
- .env.example: CADDY_BASICAUTH_HASH on dankclaw; Porkbun block
dropped from dankserver (its Caddy is gone); SEARXNG_BASE_URL to
the flat name; stale OPENAI_* block dropped (quadlet is
self-contained).
- tests: caddyfile.bats now asserts the single-Caddyfile invariant;
dnsmasq.bats cross-checks vhosts -> .143 and the retired names.
Real tokens live only in the host .env files (git-ignored):
- /home/dank/serverAppConfigs/dankclaw/.env
- /home/dank/serverAppConfigs/dankserver/.env
Token is scoped to the franksdank.cloud zone (DNS read/write).