Files
oikos/containers/122-arriman.md

9.9 KiB

122 — arriman

Docker host running the *arr stack via ezarr compose. Replaced the old yunohost-based LXC 100 on 2026-04-21.

At a glance

  • Hostname: arriman
  • IP: 192.168.8.132
  • Privilege: privileged
  • Resources: 4 cores / 8 GiB RAM / 24 GiB rootfs
  • Mounts: /mnt/library/mnt/library
  • Public hostnames: jellyseerr / qbit / sab (see below)

Compose

/home/arr/ezarr/docker-compose.yml. Network ezarr_default 172.18.0.0/16. Service users all run with primary GID 10000 (host media group) inside their containers — see media permissions. Per-app /config/<app>-config/ dirs bind to /config inside.

.env contents:

  • DOWNLOADS_DIR=/mnt/library/downloads/
  • MEDIA_DIR=/mnt/library/
  • MEDIACENTER_GID=10000must be 10000, not 13000. s6-setuidgid only honors the primary PGID; group_add: doesn't propagate. Without this, qBit errors every torrent with "Permission denied".
  • SONARR_UID=13001, RADARR_UID=13002, LIDARR_UID=13003, PROWLARR_UID=13006, JELLYSEERR_UID=13012, BAZARR_UID=13013, QBITTORRENT_UID, SABNZBD_UID

Service / port map

All services route through gluetun's network namespace. Ports are exposed via the gluetun container:

Service Host:Container Public hostname
gluetun (VPN)
sonarr 8989:8989 direct only (via gluetun)
radarr 7878:7878 direct only (via gluetun)
lidarr 8686:8686 direct only (via gluetun)
prowlarr 9696:9696 direct only (via gluetun)
bazarr 6767:6767 direct only (via gluetun)
jellyseerr 5056:5055 jellyseerr.hubris.network
qbittorrent 8080:8080 qbit.hubris.network
sabnzbd 8082:8082 HTTP, 9090:9090 HTTPS sab.hubris.network
flaresolverr 8191:8191 internal only
homarr 7575:7575 internal only

Internal *arr ↔ *arr / *arr ↔ qBit/SAB/flaresolverr comms run on localhost:<port> (services share gluetun's shared network namespace). External services reach them via gluetun:<port> (e.g. Sonarr → qBittorrent at localhost:8080 or gluetun:8080).

Categories (qBit + SAB + *arr)

Category qBit savePath SAB dir Consumer
tv /data/torrents/tv tv Sonarr
movies /data/torrents/movies movies Radarr
music /data/torrents/music music Lidarr
anime /data/torrents/anime anime Sonarr (2nd download client, root /data/media/anime)
books / audiobooks / comics / podcasts /data/torrents/<cat> <cat> (reserved, none in use yet)

Path mapping: host /mnt/library/<cat> ↔ container /data/media/<cat>. Downloads: host /mnt/library/downloads/<torrents|usenet>/<cat> ↔ container /data/torrents/<cat> and /data/usenet/<cat>.

Auth (reverse-proxy + Authentik forward-auth)

qBit

Auto-login behind forward-auth via IP whitelist. qBittorrent.conf lines:

  • WebUI\\AuthSubnetWhitelist=172.18.0.0/16, 172.17.0.0/16, 192.168.8.175/32
  • WebUI\\ReverseProxySupportEnabled=true
  • WebUI\\TrustedReverseProxiesList=192.168.8.175, 172.18.0.0/16

Stop the container before editing qBittorrent.conf. qBit writes its in-memory config on graceful shutdown and clobbers any live edits. Recipe: docker stop qbittorrent && sed -i ... && docker start qbittorrent.

Mobile/desktop clients keep working via /api/v2/* path bypass on Caddy.

SABnzbd

Gated with Authentik forward-auth (applied 2026-06-13). Caddy sab.hubris.network block uses import authentik inside a handle block. SABnzbd's own web auth is disabled:

  • html_login = 0 → no HTML login form
  • username / password cleared → CherryPy Basic Auth not activated
  • local_ranges = 172.18.0.0/16, 192.168.8.0/24, 127.0.0.0/8 → proxied requests from Caddy (192.168.8.x) and Docker-proxy (172.18.x) pass without auth

API key (67ef5a45e4e04157994e977005a33878) still works for internal service-to-service calls (Sonarr/Radarr/Lidarr via Docker internal networking — they talk to SAB at localhost:8082, not through Caddy).

host_whitelist: sabnzbd, localhost, 127.0.0.1, 192.168.8.132, sab.hubris.network — extend before accessing SAB from a new host.

Credentials

Backups of all migration-time secrets at /mnt/library/backup/arr-migration-2026-04-21/state/:

  • lxc100-apikey-{sonarr,radarr,prowlarr,lidarr}.txt
  • qbit-creds.txt, sab-creds.txt
  • lxc100-jellyseerr-settings.json

*arr API keys were preserved from the yunohost DB — don't rotate unless needed.

qBittorrent: admin / CDyjxMKvjfGupCKzXFkjsKw4nRrXMRL.

Migration gotchas (apply if ever re-importing)

  • Imported *arr config.xml: must have <BindAddress>*</BindAddress>, <Port>{ezarr-port}</Port>, <UrlBase></UrlBase>. Otherwise app listens only on 127.0.0.1, wrong port, wrong path.
  • Imported DB paths must be rewritten /mnt/library//data/media/ (RootFolders / Series / Movies / Artists tables). Without this, scans and imports fail silently.
  • Bazarr config/config.yaml (yaml, not ini) — ip: 0.0.0.0, port: 6767, empty top-level base_url; sonarr/radarr connection sections normalized to docker service names.
  • Staging dir for migrations: /mnt/library/backup/stage/<app>/ (visible to both old LXC 100 and arriman because both bind-mount the same host path).

Permissions

Member of media GID 10000. The LXC has www-data, audiobookshelf, radarr, sonarr, lidarr, prowlarr, qbittorrent, bazarr, jellyseerr, mylar, jackett, overseerr, plex, arr in the media group. Each docker container also receives GID 10000 as its primary group via MEDIACENTER_GID=10000.

Rollback material (kept until 2026-04-28+)

/mnt/library/backup/arr-migration-2026-04-21/:

  • tars/ — per-subtree tars of yunohost app data (granular restore)
  • snapshots/ — vzdumps of LXC 100 (pre-migration) and LXC 122 (pre-import), plus post-stop vzdumps of LXC 100 + 106
  • stage/<app>-preimport.tar.gz — original empty ezarr /config/<app>-config/ dirs
  • state/ — service dumps, listening ports, API keys, jellyseerr settings at migration time
  • DESTROY_AFTER_2026-04-28.md — destroy checklist + post-destroy restore commands

Changelog

2026-06-13 — SABnzbd gated with Authentik forward-auth

SABnzbd now uses Authentik forward-auth (same import authentik Caddy pattern as qBit). SABnzbd's own web auth disabled: html_login=0, credentials cleared, local_ranges extended to cover Docker bridge + homelab LAN. API key still works for internal *arr service calls. See Auth section above.

2026-06-04 — all arr services moved behind gluetun VPN; SAB port conflict fixed

  • All services (sonarr, radarr, lidarr, bazarr, prowlarr, jellyseerr, homarr, flaresolverr) now use network_mode: service:gluetun — whole stack routes through the VPN
  • Port mappings moved from individual services to gluetun container
  • Fixed SABnzbd port conflict: was crashing in a restart loop because qBittorrent held port 8080 inside the shared gluetun namespace. Changed SAB internal port to 8082 (config at /config/sabnzbd-config/sabnzbd.ini)
  • Caddy sab.hubris.network updated to point to :8082
  • Jellyseerr's extra_hosts (auth.hubris.network) moved to gluetun since extra_hosts conflicts with network_mode

2026-06-02 — ProtonVPN added (gluetun); LXC IP set static

  • Added gluetun container to compose as a WireGuard VPN sidecar (ProtonVPN, server AL#57, located in Tirana, Albania)
  • qbittorrent and sabnzbd now use network_mode: service:gluetun — all traffic routes through the VPN
  • Ports 8080 (qBit WebUI), 6881 tcp/udp (qBit BT), 8081 (SAB WebUI) exposed through gluetun
  • gluetun config at gluetun-config/wireguard/wg0.conf (read-only mount)
  • Healthcheck on gluetun; qBit/SAB wait for service_healthy before starting
  • LXC IP changed from DHCP to static (192.168.8.132) via pct set + /etc/network/interfaces
  • After first start: Sonarr/Radarr/Lidarr download client host needs updating from qbittorrentgluetun (SAB similarly sabnzbdgluetun)
  • Also fixed: 7 other DHCP LXCs (101 jellyfin, 103 paperless, 104 gitea, 105 apps, 114 nextcloud, 118 elementsynapse, 120 mule-images, 121 caddy) set to static IPs to prevent floating on reboot. See infrastructure/dns.md.

2026-04-28 — wiki entry created

Initial documentation.

2026-04-26 — MEDIACENTER_GID flipped 13000 → 10000

qBit was erroring every torrent with "Permission denied" because s6-setuidgid only honors the primary PGID and group_add: doesn't propagate. Setting the primary GID to 10000 (the host media group) fixed it.

2026-04-21 — *arr stack migrated yunohost → docker-compose

Old LXC 100 stopped; ezarr stack stood up here; data and DBs imported with path rewrites. flaresolverr folded in from old LXC 106. Three Caddy sites added (jellyseerr, qbit, sab) → see caddy. Rollback artifacts under /mnt/library/backup/arr-migration-2026-04-21/.