docs: OKF v0.1 compliance pass + fact-check + 3 research briefs
- Migrate all 127 non-reserved docs to OKF v0.1 frontmatter (type/description/tags/timestamp); fix 13 YAML issues, 2 duplicate-FM blocks, strip reserved-page FM - Restructure log.md to OKF (## YYYY-MM-DD, newest-first) - Fact-check against scripts/AGENTS.md ground truth: fix 6 false 'Active' banners on retired runbooks, 96->114 GiB GTT, deployment.md vs deploy-plan.py/deploy-remote.sh, Deployment Flow frank-medium=Quadlet, Calibre 9.9.0->9.15.0 + CVE-2025-7404 conflation, Copyparty v1.20.24, RomM 5.3.0 breaking change - Move *arr docs to new FrankBook-Pro/ section (git mv, link-safe) - Write active runbook bodies from ground truth (frank-large, frank-small) - Add 3 research briefs + HTML report: Local TTS and Voice Cloning, AI Job Search and Resume Tools, Most Popular Self-Hosted AI Apps (Jun-Sep 2026) - Add upstream-version rows to ComfyUI/OpenWebUI/Hermes app docs - All 336 tests pass; 136 pages, 0 unresolved wikilinks
This commit is contained in:
@@ -1,189 +0,0 @@
|
||||
---
|
||||
type: reference
|
||||
title: *arr Stack
|
||||
description: The *arr automation stack (Prowlarr, Sonarr, Radarr, Lidarr, Readarr, qBittorrent) — FrankBook-Pro only, every container on the gluetun WireGuard netns (all egress VPN): topology, wiring, auth posture, and gotchas.
|
||||
tags: [arr-stack, prowlarr, sonarr, radarr, lidarr, readarr, qbittorrent, frankbook-pro, dankserver]
|
||||
timestamp: 2026-09-04T00:00:00Z
|
||||
---
|
||||
|
||||
# *arr Stack
|
||||
|
||||
The *arr suite is a collection of automated media management tools for Usenet
|
||||
and BitTorrent. It runs in exactly one place: **FrankBook-Pro** — the Mac mini
|
||||
that fronts this household's downloads — as quadlet units inside its podman
|
||||
machine, with every container (the five arrs AND qBittorrent) sharing the
|
||||
[[Gluetun]] WireGuard tunnel's network namespace so **all egress exits
|
||||
through the VPN**. A short-lived Dankserver compose copy was removed on
|
||||
2026-09-04 (see below). The stack provides automatic downloading and library
|
||||
management that Copyparty alone does not cover: quality profile enforcement,
|
||||
series/movie discovery, metadata enrichment, and automated file organization.
|
||||
|
||||
The core chain is: **Prowlarr** (indexer API aggregator) →
|
||||
**Sonarr/Radarr/Lidarr/Readarr** (media-specific managers) → **qBittorrent**
|
||||
(download client, sharing the [[Gluetun]] WireGuard tunnel netns) →
|
||||
**Jellyfin** (media server scan → auto-refresh).
|
||||
|
||||
## Service Overview
|
||||
|
||||
| Service | Role | Image | Port | Min RAM |
|
||||
|---------|------|-------|------|---------|
|
||||
| Prowlarr | Indexer management | `lscr.io/linuxserver/prowlarr:latest` | 9696 | 256 MB |
|
||||
| Radarr | Movie management | `lscr.io/linuxserver/radarr:latest` | 7878 | 512 MB |
|
||||
| Sonarr | TV show management | `lscr.io/linuxserver/sonarr:latest` | 8989 | 512 MB |
|
||||
| Lidarr | Music management | `lscr.io/linuxserver/lidarr:latest` | 8686 | 256 MB |
|
||||
| Readarr | Ebook/audiobook management | `lscr.io/linuxserver/readarr:amd64-1.0.980` (pinned — LSIO ships no untagged `latest` for readarr) | 8787 | 256 MB |
|
||||
| qBittorrent | Torrent download client | `lscr.io/linuxserver/qbittorrent:4.6.7` (pinned; see [[qBittorrent]]) | 8080 (published by the gluetun unit) | 512 MB |
|
||||
|
||||
Jackett and Whisparr were evaluated as optional extras but never deployed
|
||||
(no unit, no vhost, no live container).
|
||||
|
||||
## Deployment shape (current)
|
||||
|
||||
Each service is a quadlet `.container` unit in this repo under
|
||||
`frankbook-pro/<svc>/quadlet/`, installed inside the podman machine at
|
||||
`/home/core/.config/containers/systemd/<svc>.service` by the frankbook-pro
|
||||
handler in `scripts/deploy-remote.sh`. Every unit runs with
|
||||
`PUID=0 PGID=0 TZ=America/Los_Angeles UMASK_SET=022`, mounts its config root at
|
||||
`/Volumes/COMPLETE/<svc>-data:/config`, publishes its API port on the host, and
|
||||
runs `Restart=always` with `TimeoutStartSec=900`.
|
||||
|
||||
qBittorrent is special: it shares the [[Gluetun]] container's network namespace
|
||||
(`Network=gluetun.container`) so torrent egress never touches the residential
|
||||
IP. A netns-sharer publishes no ports of its own — qB's WebUI (8080) and
|
||||
BitTorrent port (6881 TCP+UDP) are published on the gluetun unit instead.
|
||||
|
||||
## Dankserver compose copy (removed 2026-09-04)
|
||||
|
||||
A copy of the stack lived in `dankserver/compose.yaml` (`/opt/<svc>/config`
|
||||
data roots) from 2026-08-20 to 2026-09-04 and never ran healthy: the config
|
||||
dirs were created root-owned (`root:root 755`), so every app died at logger
|
||||
init (`UnauthorizedAccessException: Access to the path '/config/Sentry' is
|
||||
denied`) before binding any port — which read as dead ports, not a boot
|
||||
crash, until `podman logs <svc>` was checked. After a one-day revival it was
|
||||
removed by operator decision: **FrankBook-Pro is the sole *arr deployment.**
|
||||
Config roots moved to `~/.AGENTTRASH/20260904-dankserver-arr-teardown/` on
|
||||
Dankserver (recoverable until purged).
|
||||
|
||||
### Rootless identity model on Dankserver (verified, keep for reference)
|
||||
|
||||
- On Dankserver's podman 5.7.0 rootless, a container's default user namespace
|
||||
maps **container root (PUID=0) → host uid 1000 (dank)** and container uid
|
||||
*N* → host `100000 + N - 1`. Verified via `/proc/<pid>/uid_map`
|
||||
(`0 1000 1` / `1 100000 65536`) across plex, tautulli, jellyfin,
|
||||
calibre-web, copyparty, romm. This is why PUID=0 services write as `dank`
|
||||
and why data roots are owned `1000:1000` on that host.
|
||||
- **Never add `userns_mode: host` to a podman-compose service.**
|
||||
podman-compose 1.5.0 runs every compose service inside a pod, and podman
|
||||
rejects the combination (`--userns and --pod cannot be set together`) —
|
||||
the stack then fails to recreate with no recourse. The default mapping
|
||||
already gives the fleet identity; PUID=0 + `1000:1000`-owned data roots is
|
||||
the whole recipe. (The compose file briefly carried `userns_mode: host` on
|
||||
all six arr services on 2026-09-04 — reverted in `e454159`, same day.)
|
||||
- qBittorrent's first boot (PUID=0, empty config) prints a one-time WebUI
|
||||
admin password in `podman logs qbittorrent` — persist it via the PBKDF2
|
||||
recipe in [[qBittorrent]] before restarting the container.
|
||||
|
||||
## Access / auth posture
|
||||
|
||||
No *arr app sits behind the Anubis guard chain — the stack is exempt by
|
||||
construction (its own auth), with an exemption comment in the Caddyfile per
|
||||
vhost. Five TLS vhosts (`<svc>.franksdank.cloud`) terminate on Caddy on
|
||||
Dankclaw and route to FrankBook-Pro's published ports
|
||||
(`192.168.0.112:<port>`, all exposed by the gluetun unit since the netns
|
||||
consolidation); the same ports are reachable directly on the LAN. Sonarr is
|
||||
the exception: internal-only by construction — no vhost, no public DNS record;
|
||||
admins reach it at `http://192.168.0.112:8989` from the LAN only (retired
|
||||
2026-09-04; users request TV through [[Seerr]] instead).
|
||||
|
||||
Auth-config history (verified live 2026-08-29): all five arrs shipped with
|
||||
`AuthenticationMethod=None` **plus** `AuthenticationRequired=Enabled`. On the
|
||||
v1 (.NET) apps that combo is self-contradictory — UI Save is permanently
|
||||
disabled and any settings save throws `DryIoc.ScopedItemException` inside
|
||||
`AuthorizationMiddleware` (500 sprawl on every page after restart). The valid
|
||||
representation of "no auth" in v1 is **absence of the `<AuthenticationRequired>`
|
||||
key**, not the literal string `Disabled` — readarr's config (key absent) booted
|
||||
clean while its three siblings (key=`Disabled`) 500-sprawled, which is how it
|
||||
was caught. Fix applied live: key deleted on sonarr/radarr/lidarr/prowlarr,
|
||||
containers restarted, all five verified serving. Posture = zero-auth arrs on
|
||||
LAN and WAN; the Anubis wall guards homepage/search/hermes/prometheus/romm/files
|
||||
but **not** the arrs — first-account-wins is the current race condition if that
|
||||
ever flips to `External` auth (needs an IdP first; auth method choice remains an
|
||||
operator decision). Sonarr is exempt from even that exposure since 2026-09-04:
|
||||
with no vhost and no public DNS record, its zero-auth UI has no WAN path at all.
|
||||
|
||||
## Chain wiring (verified live 2026-08-30)
|
||||
|
||||
The download chain is wired and test-first verified: **indexers → Prowlarr →
|
||||
per-arr qBittorrent clients (category = app name) → import**.
|
||||
|
||||
- qB webUI auth is ON (`admin` + generated password; verify before writing it
|
||||
into any config — it was generated at first boot, not a default).
|
||||
- Per-arr QBittorrent download clients exist on sonarr/radarr/lidarr
|
||||
(enabled) and readarr (**parked**: its qB proxy fails auth live even with
|
||||
correct creds — known defect of the abandoned upstream; retest needed
|
||||
after the 2026-09-04 netns move). All four clients were re-pointed to
|
||||
**loopback** (`127.0.0.1:8080`, same netns) on 2026-09-04 when the arrs
|
||||
joined gluetun's netns — the old `10.88.0.1:8080` gateway hack routes
|
||||
into the VPN tunnel (AllowedIPs=0.0.0.0/0) and is dead from inside the
|
||||
netns. Verified live: `podman exec sonarr curl` reaches qB with 200, and
|
||||
a real qB login from inside the netns returns 200.
|
||||
- Prowlarr runs v2.5.2 where apps are first-class rows (`Applications`
|
||||
table): four Application rows (sonarr/radarr/lidarr/readarr) carried each
|
||||
arr's real baseUrl+apiKey with `SyncLevel=FullSync` as of 2026-08-30.
|
||||
**Status 2026-09-04: the table is EMPTY again** (live API check — 8 rows,
|
||||
all Cardigann/Torznab, zero Application rows; lost with the dankserver
|
||||
config migration). Prowlarr sync is broken until the four rows are
|
||||
rebuilt with baseUrl `127.0.0.1:<arr port>` (same netns).
|
||||
- Indexers are **test-before-enable**: EZTV and 1337x stay disabled with
|
||||
reason "blocked by CloudFlare Protection" (this host's egress ASN was
|
||||
CF-blocked at those trackers). **2026-09-04: arr egress moved onto the
|
||||
ProtonVPN tunnel** — the parked reason may no longer hold; retest before
|
||||
enabling. Nyaa.si, sukebei, RuTor, Byrutor, YTS passed live tests and
|
||||
are enabled. A failed test = parked with reason, never enabled blind.
|
||||
- Prowlarr v2 sync model: indexers stay in Prowlarr; arrs search *through* it
|
||||
and hand off to their own qB download client (category routing). Mappings
|
||||
materialize at grab time — zero mappings right after wiring is expected,
|
||||
not a fault.
|
||||
|
||||
## Disk layout (current)
|
||||
|
||||
```
|
||||
/Volumes/COMPLETE <- completed-media volume (Mac volume)
|
||||
├── sonarr-data:/config <- per-app config roots, one per unit
|
||||
├── radarr-data:/config
|
||||
├── lidarr-data:/config
|
||||
├── readarr-data:/config
|
||||
├── qbittorrent-data:/config
|
||||
└── <movie/tv/music/books roots> <- arr import roots live here
|
||||
/Volumes/INCOMPLETE <- qB in-flight downloads (same path inside qB)
|
||||
```
|
||||
|
||||
qB mounts both volumes at their identical host paths
|
||||
(`Volume=/Volumes/COMPLETE:/Volumes/COMPLETE`,
|
||||
`Volume=/Volumes/INCOMPLETE:/Volumes/INCOMPLETE`), so a category's download path
|
||||
is the same string on every container that touches it — no remapping between
|
||||
download and import.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **Timezone:** every unit runs `TZ=America/Los_Angeles`; Sonarr's scheduler is timezone-sensitive — keep them uniform.
|
||||
- **File permissions:** `UMASK_SET=022` on qBittorrent; arr apps run PUID=0 so they can read/move qB downloads.
|
||||
- **Network conflicts:** *arr apps use many ports. On the machine VM, only the API ports (8989/7878/8686/8787/9696) and gluetun's published 8080 + 6881 are host-published; netns-sharers (qB) publish none of their own.
|
||||
- **Prowlarr API key rotation:** If rotated, update it in every arr app (`Applications` table rows carry the real keys).
|
||||
- **qBittorrent WebUI password:** generated at first boot, not a default — persist it via the PBKDF2 conf recipe in [[qBittorrent]] before any restart.
|
||||
- **Readarr stability:** abandoned upstream (retired May 2026); its qB download client is parked pending a successor image. Do not rely on it for mission-critical collections.
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. Use tags to route content to specific download clients or categories.
|
||||
2. Enable the Blocklist in arr apps to prevent re-downloading failed torrents.
|
||||
3. Set download limits in qBittorrent to avoid bandwidth saturation.
|
||||
4. Back up arr configs regularly (they are small SQLite DBs + JSON) — each lives at `/Volumes/COMPLETE/<svc>-data/config`.
|
||||
5. Monitor Prowlarr indexer health — broken indexers hide new content.
|
||||
6. Start with default quality profiles. Add custom formats gradually.
|
||||
|
||||
## See Also
|
||||
|
||||
- [[Sonarr]] · [[Radarr]] · [[Lidarr]] · [[Readarr]] · [[Prowlarr]] · [[qBittorrent]] — per-service pages
|
||||
- [[Jellyfin]] — media server that consumes *arr downloads
|
||||
- [[Copyparty]] — alternative file viewer
|
||||
@@ -1,3 +1,12 @@
|
||||
---
|
||||
type: reference
|
||||
description: "Calibre-Web is a web application that browses, reads, and downloads eBooks from an existing Calibre library database."
|
||||
tags:
|
||||
- dankserver
|
||||
- calibre
|
||||
timestamp: 2026-09-03
|
||||
---
|
||||
|
||||
# Calibre-Web
|
||||
|
||||
Calibre-Web is a web application that browses, reads, and downloads eBooks from an existing Calibre library database. It serves as the web frontend for the Calibre e-book manager.
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
---
|
||||
type: reference
|
||||
description: "Calibre is the e-book library manager that backs Calibre-Web."
|
||||
tags:
|
||||
- dankserver
|
||||
- calibre
|
||||
timestamp: 2026-09-21
|
||||
---
|
||||
|
||||
# Calibre
|
||||
|
||||
Calibre is the e-book library manager that backs Calibre-Web. It manages metadata, formats, and conversions for the library that Calibre-Web serves.
|
||||
@@ -18,10 +27,10 @@ The actual library files (`.epub`, `.mobi`, `.pdf`) and the Calibre database (`.
|
||||
|
||||
## Current Version
|
||||
|
||||
Calibre 9.2.1 is the version on the live host (9.9.0 is the upstream latest). Major features include:
|
||||
Calibre 9.15.0 is the version on the live host (the upstream latest as of 2026-09-22). Major features include:
|
||||
- Bookshelf view
|
||||
- Opt-in AI features
|
||||
- Content server security fix (CVE-2025-7404 equivalent): a bug since v6.16.0 allows any user with server access to read non-Calibre files on the host. Upgrade to 9.9.0+ if serving content to untrusted users.
|
||||
- Content-server path-traversal fix: a bug since v6.16.0 allowed any user with server access to read non-Calibre files on the host. (The CVE-2025-7404 advisory is tracked against Calibre-Web, see [[Calibre-Web]].) Upgrade to 9.15.0+ if serving content to untrusted users.
|
||||
|
||||
## Library Directory
|
||||
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
---
|
||||
type: reference
|
||||
description: "Copyparty is a lightweight file server and media streamer that runs as a single Python binary."
|
||||
tags:
|
||||
- dankserver
|
||||
- copyparty
|
||||
timestamp: 2026-09-03
|
||||
---
|
||||
|
||||
# Copyparty
|
||||
|
||||
Copyparty is a lightweight file server and media streamer that runs as a single Python binary. It handles large payloads, media streaming, resumable uploads, directory browsing, and WebDAV from one process.
|
||||
@@ -11,7 +20,7 @@ LAN — **Docs:** https://github.com/9001/copyparty
|
||||
|
||||
| Item | Value |
|
||||
|------|-------|
|
||||
| Running image | `ghcr.io/9001/copyparty-ac:latest` (ac = full edition; the bare `copyparty:latest` tag does not exist — ghcr answers 403 on the token request for nonexistent repos). Version at research time (2026-08): v1.20.21 |
|
||||
| Running image | `ghcr.io/9001/copyparty-ac:latest` (ac = full edition; the bare `copyparty:latest` tag does not exist — ghcr answers 403 on the token request for nonexistent repos). Upstream latest v1.20.24 (2026-09-19); v1.20.21 at research time (2026-08) |
|
||||
| Port | 3923 (host) → 3923 (container) |
|
||||
| Volume | bind mount the shared root directory |
|
||||
| Auth | Per-directory `.cpy` config files, HTTP basic auth, `dirkeys`, `filekeys` |
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
---
|
||||
type: reference
|
||||
description: "Dankserver (192.168.0.235) runs the media and library stack."
|
||||
tags:
|
||||
- dankserver
|
||||
timestamp: 2026-09-03
|
||||
---
|
||||
|
||||
# Dankserver Stack
|
||||
|
||||
Dankserver (192.168.0.235) runs the media and library stack. Public access
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
---
|
||||
type: reference
|
||||
description: "The Dankserver entropy volume is a RAID-backed LUKS filesystem mounted at"
|
||||
tags:
|
||||
- dankserver
|
||||
timestamp: 2026-08-28
|
||||
---
|
||||
|
||||
# Entropy Volume
|
||||
|
||||
The Dankserver entropy volume is a RAID-backed LUKS filesystem mounted at
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
---
|
||||
type: reference
|
||||
description: "Plex Media Server is a **containerized media server on Dankserver**: a podman"
|
||||
tags:
|
||||
- dankserver
|
||||
- plex
|
||||
timestamp: 2026-09-15
|
||||
---
|
||||
|
||||
# Plex
|
||||
|
||||
Plex Media Server is a **containerized media server on Dankserver**: a podman
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
---
|
||||
type: reference
|
||||
description: "This guide covers metadata providers, cover art, ROM naming conventions, emulator integration, and the scraping workflow for RomM on Dankserver."
|
||||
tags:
|
||||
- dankserver
|
||||
- romm
|
||||
timestamp: 2026-08-28
|
||||
---
|
||||
|
||||
# RomM Scraping & Asset Management
|
||||
|
||||
This guide covers metadata providers, cover art, ROM naming conventions, emulator integration, and the scraping workflow for RomM on Dankserver.
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
---
|
||||
type: reference
|
||||
description: "RomM (ROM Manager) is a self-hosted ROM library manager and player."
|
||||
tags:
|
||||
- dankserver
|
||||
- romm
|
||||
timestamp: 2026-09-03
|
||||
---
|
||||
|
||||
# RomM
|
||||
|
||||
RomM (ROM Manager) is a self-hosted ROM library manager and player. It scans a ROM collection, enriches it with metadata and cover art from multiple providers, and serves it through a clean web interface. RomM also supports browser-based emulation via EmulatorJS and native emulator streaming.
|
||||
@@ -208,6 +217,7 @@ healthcheck:
|
||||
|
||||
- **First login overwrites env credentials.** The `ROMM_PASSWORD` env var sets the initial password. After first login, the admin password is controlled in the UI. The env var only applies on first boot.
|
||||
- **MariaDB and Redis are required.** RomM 5.2.0 no longer supports SQLite-only deployments. Both MariaDB and Redis must be running.
|
||||
- **5.3.0 breaking change (2026-09-21).** `filesystem.roms_folder` / `firmware_folder` are removed; the scan root must be expressed via `filesystem.structure` in `config.yml` (see the Config File section above). New env vars: `SCAN_WORKERS`, `WEB_SERVER_CONCURRENCY`, `DB_POOL_RECYCLE_SECONDS`. The rolling `:latest` tag will pick this up on the next pull — migrate `config.yml` before redeploying, or the scan root silently goes empty.
|
||||
- **Reverse proxy cache stale index.html.** Purge Caddy proxy cache after RomM version bumps to avoid serving a stale frontend after an upgrade.
|
||||
- **RAHasher build time.** Enabling RetroAchievements hashing increases the first image build. Skip unless you need achievement data.
|
||||
- **MobyGames is paid.** The hobbyist API has strict rate limits. Screenscraper is the recommended free alternative.
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
---
|
||||
type: reference
|
||||
description: "Tautulli is the statistics, monitoring, and notification companion for"
|
||||
tags:
|
||||
- dankserver
|
||||
- tautulli
|
||||
timestamp: 2026-09-01
|
||||
---
|
||||
|
||||
# Tautulli
|
||||
|
||||
Tautulli is the statistics, monitoring, and notification companion for
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
---
|
||||
type: reference
|
||||
title: Lidarr
|
||||
description: Lidarr music manager in the *arr stack on FrankBook-Pro — live quadlet deployment, ports, volumes, and wiring facts.
|
||||
tags: [lidarr, arr-stack, frankbook-pro]
|
||||
timestamp: 2026-09-03T00:00:00Z
|
||||
---
|
||||
|
||||
# Lidarr
|
||||
|
||||
Lidarr manages music albums in the *arr stack. The stack runs on
|
||||
**FrankBook-Pro** (the Mac mini) as quadlet units inside its podman machine —
|
||||
not on Dankserver. It searches, downloads, and organizes albums from indexers
|
||||
into the Jellyfin music library.
|
||||
|
||||
**Host:** FrankBook-Pro (podman machine) — **Access:** direct port `8686` (no reverse-proxy vhost; the *arr stack is exempt by construction from the Anubis guard chain) — **Docs:** https://wiki.servarr.com/lidarr
|
||||
|
||||
## Facts
|
||||
|
||||
| Item | Value |
|
||||
|------|-------|
|
||||
| Image | `lscr.io/linuxserver/lidarr:latest` |
|
||||
| Port | 8686 (host) → 8686 (container) |
|
||||
| Env | `PUID=0`, `PGID=0`, `TZ=America/Los_Angeles`, `UMASK_SET=022` |
|
||||
| Config root | `/Volumes/COMPLETE/lidarr-data:/config` |
|
||||
| Min RAM | 256 MB |
|
||||
| Metadata | MusicBrainz |
|
||||
|
||||
## Deployment (current)
|
||||
|
||||
Quadlet unit `lidarr.container` from this repo (`frankbook-pro/lidarr/quadlet/`)
|
||||
is installed inside the podman machine at
|
||||
`/home/core/.config/containers/systemd/lidarr.service` by the frankbook-pro
|
||||
handler in `scripts/deploy-remote.sh`. Unit shape:
|
||||
|
||||
```ini
|
||||
[Container]
|
||||
ContainerName=lidarr
|
||||
Image=lscr.io/linuxserver/lidarr:latest
|
||||
Environment=PUID=0
|
||||
Environment=PGID=0
|
||||
Environment=TZ=America/Los_Angeles
|
||||
Environment=UMASK_SET=022
|
||||
Volume=/Volumes/COMPLETE/lidarr-data:/config
|
||||
PublishPort=8686:8686
|
||||
|
||||
[Service]
|
||||
TimeoutStartSec=900
|
||||
Restart=always
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
1. Add Prowlarr as the indexer source (prefer torrent-based indexers for FLAC —
|
||||
the Nyaa feed carries music categories; see [[Prowlarr]]).
|
||||
2. Add qBittorrent as the download client with the `music` category ([[qBittorrent]]).
|
||||
3. Set quality profile (Lossless → High Bitrate → Standard).
|
||||
4. Set the root folder to the music root under the COMPLETE volume.
|
||||
5. Add artists and verify downloads.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- Album variants: Lidarr supports multiple releases of the same album (vinyl vs CD). Use "Preferred" and "Cutoff" quality profiles.
|
||||
- Music videos can be optionally downloaded separately from albums.
|
||||
|
||||
## See Also
|
||||
|
||||
- [[ARR-Stack]] — full *arr stack documentation
|
||||
- [[Jellyfin]] — media server that consumes Lidarr downloads
|
||||
@@ -1,126 +0,0 @@
|
||||
---
|
||||
type: reference
|
||||
title: Prowlarr
|
||||
description: Prowlarr indexer-management layer for the *arr stack on FrankBook-Pro — feed routes, sync model, API surface, and verified live gotchas.
|
||||
tags: [prowlarr, arr-stack, frankbook-pro]
|
||||
timestamp: 2026-09-03T00:00:00Z
|
||||
---
|
||||
|
||||
# Prowlarr
|
||||
|
||||
Prowlarr is the indexer management layer for the *arr stack. It hosts the
|
||||
indexer definitions and exposes them as Torznab feeds and downloads;
|
||||
Sonarr, Radarr, Lidarr, and Readarr query those feeds and receive results.
|
||||
|
||||
**Host:** FrankBook-Pro (podman machine) — **Access:** direct port `9696` (no
|
||||
reverse-proxy vhost; the *arr stack is exempt by construction from the Anubis
|
||||
guard chain) — **Docs:** https://wiki.servarr.com/prowlarr
|
||||
|
||||
## Facts
|
||||
|
||||
| Item | Value |
|
||||
|------|-------|
|
||||
| Image | `lscr.io/linuxserver/prowlarr:latest` (runs v2.5.2 line) |
|
||||
| Port | 9696 (host) → 9696 (container) |
|
||||
| Env | `PUID=0`, `PGID=0`, `TZ=America/Los_Angeles`, `UMASK_SET=022` |
|
||||
| Config root | `/Volumes/COMPLETE/prowlarr-data:/config` |
|
||||
| Min RAM | 256 MB |
|
||||
| Auth | Forms (web UI) + API key (`/api/v1/...` and feed routes) |
|
||||
|
||||
## Deployment (current)
|
||||
|
||||
Quadlet unit `prowlarr.container` from this repo
|
||||
(`frankbook-pro/prowlarr/quadlet/`), installed inside the podman machine at
|
||||
`/home/core/.config/containers/systemd/prowlarr.service` by the frankbook-pro
|
||||
handler in `scripts/deploy-remote.sh`:
|
||||
|
||||
```ini
|
||||
[Container]
|
||||
ContainerName=prowlarr
|
||||
Image=lscr.io/linuxserver/prowlarr:latest
|
||||
Environment=PUID=0
|
||||
Environment=PGID=0
|
||||
Environment=TZ=America/Los_Angeles
|
||||
Environment=UMASK_SET=022
|
||||
Volume=/Volumes/COMPLETE/prowlarr-data:/config
|
||||
PublishPort=9696:9696
|
||||
|
||||
[Service]
|
||||
TimeoutStartSec=900
|
||||
Restart=always
|
||||
```
|
||||
|
||||
## Live wiring (verified end-to-end 2026-08-30)
|
||||
|
||||
Indexer queries flow **through** Prowlarr; a grab hands off to the querying
|
||||
app's own qBittorrent download client. Feeds are per-indexer:
|
||||
|
||||
```
|
||||
http://prowlarr:9696/{indexerId}/api?apikey={GLOBAL_KEY}&t=caps|search|tvsearch|movie|music|book&...
|
||||
http://prowlarr:9696/{indexerId}/download?link=...&file=... (torrent handoff)
|
||||
```
|
||||
|
||||
| App | Indexer row | Prowlarr id | Categories | Status |
|
||||
|---|---|---|---|---|
|
||||
| Radarr | Prowlarr-YTS | 7 | [2000] | ✅ grabbed + imported 2160p Dark Knight 2026-08-30 |
|
||||
| Sonarr | Prowlarr-Nyaa | 4 | [5000] | ✅ connection validated (202) |
|
||||
| Lidarr | Prowlarr-Nyaa | 4 | [3000] | ✅ connection validated (202) |
|
||||
| Readarr | Prowlarr-Byrutor | 3 | [7000] | indexer valid; download client parked |
|
||||
|
||||
The global API key is in `config.xml` (`<ApiKey>`); per-application keys are
|
||||
only used by Prowlarr's own sync calls, NOT by the feeds. The arr download
|
||||
clients authenticate to qBittorrent with the permanent WebUI password stored
|
||||
in `/home/dank/.qbpass` (mode 600, owner `dank`) on Dankserver — see
|
||||
[[qBittorrent]] for why that password must be pinned in the conf file.
|
||||
|
||||
**Readarr caveat:** Readarr is abandoned upstream; its qBittorrent client
|
||||
cannot authenticate against newer qB Web-API versions (`Authentication
|
||||
failure` on the connection test while Sonarr/Lidarr/Radarr pass with the same
|
||||
credentials — root cause: qB ≥ 5's 204 empty-body login success, fixed fleet-
|
||||
wide by pinning qB to 4.6.7). The books pipeline is parked pending a Readarr
|
||||
successor; the indexer row itself is healthy.
|
||||
|
||||
## Gotchas (verified live 2026-08-30)
|
||||
|
||||
- **The feed route is `/{indexerId}/api`.** There is no `/torznab/{id}/feed`
|
||||
— that path (and any other unmatched path) hits the Forms-auth catch-all
|
||||
and gets `302 → /login?returnUrl=…`. An arr following the redirect parses
|
||||
the login HTML and fails with a cryptic
|
||||
`'/' is an unexpected token … Line 54` XML error that looks like an auth
|
||||
problem. It is a path typo. Source: `NewznabController`
|
||||
(`[HttpGet("{id:int}/api")]` + absolute
|
||||
`/api/v1/indexer/{id}/newznab`).
|
||||
- **The arr's Torznab joiner is `TrimEnd(baseUrl,'/') + apiPath` with NO
|
||||
separator.** `baseUrl="…/7/" + apiPath="api"` silently becomes `…/7api`.
|
||||
Either keep the leading slash on `apiPath` (`"/api"`) or end the baseUrl
|
||||
with `/api`.
|
||||
- Categories in the indexer row must be a subset of what the feed's `caps`
|
||||
advertises; extras log "does not support the following categories" and
|
||||
some feeds reject them.
|
||||
- **A freshly created indexer row defaults to all-off.** If `enableRss`,
|
||||
`enableAutomaticSearch`, or `enableInteractiveSearch` aren't set, the
|
||||
app logs `Searching indexers for [X]. 0 active indexers` (Lidarr,
|
||||
verified). Search proves TV + music chains 2026-08-30: Sonarr returned
|
||||
76 live releases for an anime term, Lidarr 18 for YOASOBI – THE BOOK,
|
||||
all via the Prowlarr-Nyaa feed.
|
||||
- The v1 API collection is `/api/v1/applications` (not `/api/v1/app`);
|
||||
GET responses carry `fields: []` — real settings values live in
|
||||
`prowlarr.db` → `Applications.Settings` JSON (read-only inspection).
|
||||
- Instance name/`InstanceName=Prowlarr` in `config.xml` does NOT prefix the
|
||||
API/feed routes on this build (they answer at root; the `/Prowlarr/...`
|
||||
prefix 302s to the SPA).
|
||||
- **Application auto-sync model (v2):** Applications are first-class rows in
|
||||
the `Applications` table; each of the four app rows (sonarr/radarr/lidarr/
|
||||
readarr) carries the real baseUrl+apiKey with `SyncLevel=FullSync`. The
|
||||
earlier v1-era failure where `POST /api/v1/applications/test` threw
|
||||
`Unable to cast object of type 'NzbDrone.Core.Thing…'` (v1 could not
|
||||
deserialize Radarr 6.3's newer response types) is historical — it was the
|
||||
reason the manual Torznab rows were created in the first place.
|
||||
- Prowlarr runs `AuthenticationMethod=Forms` + `AuthenticationRequired=Enabled`
|
||||
healthily — the DryIoc crash combo was `None`+`Enabled` only (see
|
||||
[[radarr]] auth notes).
|
||||
|
||||
## See Also
|
||||
|
||||
- [[ARR-Stack]] — full *arr stack documentation
|
||||
- [[Radarr]] · [[Sonarr]] · [[Lidarr]] · [[Readarr]] · [[qBittorrent]]
|
||||
@@ -1,117 +0,0 @@
|
||||
---
|
||||
type: reference
|
||||
title: qBittorrent
|
||||
description: qBittorrent download client for the *arr stack — pinned 4.6.7 on FrankBook-Pro, shares the Gluetun WireGuard netns, PBKDF2 WebUI credential recipe.
|
||||
tags: [qbittorrent, arr-stack, frankbook-pro, gluetun]
|
||||
timestamp: 2026-09-03T00:00:00Z
|
||||
---
|
||||
|
||||
# qBittorrent
|
||||
|
||||
qBittorrent is the torrent download client for the *arr stack. The stack runs on
|
||||
**FrankBook-Pro** (the Mac mini) as quadlet units inside its podman machine —
|
||||
not on Dankserver. It receives download requests from Sonarr, Radarr, Lidarr,
|
||||
and Readarr via category tagging.
|
||||
|
||||
**Host:** FrankBook-Pro (podman machine) — **Access:** WebUI on port `8080`,
|
||||
published by the [[Gluetun]] unit because qBittorrent shares that container's
|
||||
network namespace (a netns-sharer publishes no ports of its own).
|
||||
|
||||
## Facts
|
||||
|
||||
| Item | Value |
|
||||
|------|-------|
|
||||
| Image | `lscr.io/linuxserver/qbittorrent:4.6.7` — **pinned**, see the pin rationale below |
|
||||
| Network | `Network=gluetun.container` (torrent egress exits via the WireGuard/ProtonVPN tunnel) |
|
||||
| Ports | 8080 (WebUI) and 6881 TCP+UDP published on the gluetun unit |
|
||||
| Env | `PUID=0`, `PGID=0`, `TZ=America/Los_Angeles`, `UMASK_SET=022` |
|
||||
| Volumes | `/Volumes/COMPLETE/qbittorrent-data:/config`, plus `/Volumes/COMPLETE` and `/Volumes/INCOMPLETE` mounted at identical paths |
|
||||
| Auth | Web UI username/password (`admin` + generated password); LAN bypass not used |
|
||||
|
||||
## Why the 4.6.7 pin exists (2026-09-01)
|
||||
|
||||
Readarr's abandoned qBittorrent client rejects qB ≥ 5's **204 empty-body login
|
||||
success** as `Authentication failure` — a runtime break, not just an API-create
|
||||
issue. The fleet pins `lscr.io/linuxserver/qbittorrent:4.6.7` while Readarr is
|
||||
in the stack. **Never unpin to `latest` while Readarr is in the fleet.**
|
||||
|
||||
Second trap on any version flip: qB 5.x's shutdown conf rewrite leaves a
|
||||
`WebUI\Password_PBKDF2=@ByteArray(...)` line that 4.6.7 rejects — every login
|
||||
then returns "invalid credentials" (the arrs included). Fix = rewrite the same
|
||||
conf line with the same password while qB is stopped.
|
||||
|
||||
## Persistent WebUI credentials (verified 2026-08-30)
|
||||
|
||||
qBittorrent 5 mints a **new temporary password at every start** unless a
|
||||
password is stored in `qBittorrent.conf`. That rotation silently breaks every
|
||||
arr download client after each reboot. The Web-API has no password endpoint
|
||||
any more (`/api/v2/app/setPassword` was removed), and the linuxserver image
|
||||
has no `WEBUI_AUTH` handling — so persistence must be written to the conf
|
||||
directly, in qb's own `salt:hash` format (`src/base/utils/password.cpp`:
|
||||
PBKDF2-HMAC-SHA512, 100 000 iterations, 16-byte salt = 4×uint32, then
|
||||
`base64(salt) + ":" + base64(hash)` as the raw value):
|
||||
|
||||
```python
|
||||
import base64, hashlib, os
|
||||
salt = os.urandom(16)
|
||||
h = hashlib.pbkdf2_hmac("sha512", password.encode(), salt, 100000, 64)
|
||||
val = (base64.b64encode(salt) + b":" + base64.b64encode(h)).decode()
|
||||
# with the container STOPPED, in [Preferences]:
|
||||
# WebUI\Username=admin
|
||||
# WebUI\Password_PBKDF2=<val>
|
||||
```
|
||||
|
||||
Then `podman start qbittorrent` and confirm login survives a
|
||||
`podman restart` — the temp-password rotation stops the moment stored
|
||||
credentials verify. The chosen value lives host-local in `/home/dank/.qbpass`
|
||||
(mode 600, owner `dank`) — never in git; every arr download client and
|
||||
[[Prowlarr]] reference it. (The classic `@ByteArray(salt+hash)` form is WRONG
|
||||
for qb5: login 401s on it; verify() base64-decodes the two halves separately.)
|
||||
|
||||
## Deployment (current)
|
||||
|
||||
Quadlet unit `qbittorrent.container` from this repo
|
||||
(`frankbook-pro/qbittorrent/quadlet/`), installed inside the podman machine at
|
||||
`/home/core/.config/containers/systemd/qbittorrent.service` by the
|
||||
frankbook-pro handler in `scripts/deploy-remote.sh`:
|
||||
|
||||
```ini
|
||||
[Container]
|
||||
ContainerName=qbittorrent
|
||||
Image=lscr.io/linuxserver/qbittorrent:4.6.7
|
||||
Network=gluetun.container
|
||||
Environment=PUID=0
|
||||
Environment=PGID=0
|
||||
Environment=TZ=America/Los_Angeles
|
||||
Environment=UMASK_SET=022
|
||||
Volume=/Volumes/COMPLETE/qbittorrent-data:/config
|
||||
Volume=/Volumes/COMPLETE:/Volumes/COMPLETE
|
||||
Volume=/Volumes/INCOMPLETE:/Volumes/INCOMPLETE
|
||||
|
||||
[Service]
|
||||
TimeoutStartSec=900
|
||||
Restart=always
|
||||
```
|
||||
|
||||
## Gotchas (verified live)
|
||||
|
||||
- Temporary-password rotation on every boot is the default state of an
|
||||
untouched qb5 — see the persistence recipe above; without it, all arr
|
||||
download clients silently fail queue adds ("Couldn't add release … to
|
||||
download queue" in the arr logs) after any restart.
|
||||
- API login from `curl` needs a `Referer: http://<host>:<port>/` header
|
||||
(CSRF protection) or POSTs get rejected even with a valid SID.
|
||||
- Cookie-name quirk by version: qB 5.x names its WebUI session cookie
|
||||
`QBT_SID_<port>`; 4.6.7 uses plain `SID`. Any automation must parse the
|
||||
cookie generically (e.g. `grep -oE '[A-Za-z_]*SID[A-Za-z0-9_]*=[^;[:space:]]*'`)
|
||||
instead of hard-coding a port-suffixed name, or it fails with 403 cascades
|
||||
that never reach qB as failed logins.
|
||||
- Egress verification for this stack must run **inside the gluetun container**
|
||||
(`podman exec gluetun wget -qO- https://ipinfo.io/json`); running the same
|
||||
probe one ssh-context out returns the residential IP — a false leak alarm.
|
||||
- Ensure umask is set to `022` so downloaded files are readable by arr apps.
|
||||
|
||||
## See Also
|
||||
|
||||
- [[ARR-Stack]] — full *arr stack documentation
|
||||
- [[Gluetun]] — the WireGuard tunnel this container shares
|
||||
@@ -1,71 +0,0 @@
|
||||
---
|
||||
type: reference
|
||||
title: Radarr
|
||||
description: Radarr movie manager in the *arr stack on FrankBook-Pro — live quadlet deployment, ports, volumes, and wiring facts.
|
||||
tags: [radarr, arr-stack, frankbook-pro]
|
||||
timestamp: 2026-09-03T00:00:00Z
|
||||
---
|
||||
|
||||
# Radarr
|
||||
|
||||
Radarr manages movies in the *arr stack. The stack runs on **FrankBook-Pro**
|
||||
(the Mac mini) as quadlet units inside its podman machine — not on Dankserver.
|
||||
It searches, downloads, and organizes movies from indexers into the Jellyfin
|
||||
movie library.
|
||||
|
||||
**Host:** FrankBook-Pro (podman machine) — **Access:** direct port `7878` (no reverse-proxy vhost; the *arr stack is exempt by construction from the Anubis guard chain) — **Docs:** https://wiki.servarr.com/radarr
|
||||
|
||||
## Facts
|
||||
|
||||
| Item | Value |
|
||||
|------|-------|
|
||||
| Image | `lscr.io/linuxserver/radarr:latest` (v6 line; v6.3.x verified live 2026-08-30) |
|
||||
| Port | 7878 (host) → 7878 (container) |
|
||||
| Env | `PUID=0`, `PGID=0`, `TZ=America/Los_Angeles`, `UMASK_SET=022` |
|
||||
| Config root | `/Volumes/COMPLETE/radarr-data:/config` |
|
||||
| Min RAM | 512 MB |
|
||||
| Metadata | TMDB / TheMovieDB API |
|
||||
|
||||
## Deployment (current)
|
||||
|
||||
Quadlet unit `radarr.container` from this repo (`frankbook-pro/radarr/quadlet/`)
|
||||
is installed inside the podman machine at
|
||||
`/home/core/.config/containers/systemd/radarr.service` by the frankbook-pro
|
||||
handler in `scripts/deploy-remote.sh`. Unit shape:
|
||||
|
||||
```ini
|
||||
[Container]
|
||||
ContainerName=radarr
|
||||
Image=lscr.io/linuxserver/radarr:latest
|
||||
Environment=PUID=0
|
||||
Environment=PGID=0
|
||||
Environment=TZ=America/Los_Angeles
|
||||
Environment=UMASK_SET=022
|
||||
Volume=/Volumes/COMPLETE/radarr-data:/config
|
||||
PublishPort=7878:7878
|
||||
|
||||
[Service]
|
||||
TimeoutStartSec=900
|
||||
Restart=always
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
1. Add Prowlarr as the indexer source (the YTS indexer row feeds Radarr — see [[Prowlarr]]).
|
||||
2. Add qBittorrent as the download client with the `movies` category ([[qBittorrent]]).
|
||||
3. Set quality profile and cutoff quality.
|
||||
4. Set the root folder to the movies root under the COMPLETE volume (Radarr
|
||||
imports from where [[qBittorrent]] drops completed downloads; first verified
|
||||
grab+import was a 2160p Dark Knight test on 2026-08-30).
|
||||
5. Add movies and verify downloads.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- Radarr v6 is the current stable (v6.3.x as of 2026-08). `:latest` points to the current release.
|
||||
- Movie renaming produces `Title (Year)` format. Jellyfin scanner handles this.
|
||||
- File permissions: qBittorrent downloads as PUID=0; arr apps must read/move files.
|
||||
|
||||
## See Also
|
||||
|
||||
- [[ARR-Stack]] — full *arr stack documentation
|
||||
- [[Jellyfin]] — media server that consumes Radarr downloads
|
||||
@@ -1,83 +0,0 @@
|
||||
---
|
||||
type: reference
|
||||
title: Readarr
|
||||
description: Readarr ebook/audiobook manager in the *arr stack on FrankBook-Pro — retired upstream, pinned image, parked qB download client.
|
||||
tags: [readarr, arr-stack, frankbook-pro]
|
||||
timestamp: 2026-09-03T00:00:00Z
|
||||
---
|
||||
|
||||
# Readarr
|
||||
|
||||
> **RETIRED UPSTREAM (May 2026).** The Servarr Team retired Readarr: its
|
||||
> metadata became unusable and the community migration to Open Library stalled.
|
||||
> There is no upstream development. Alternatives: the Bookshelf community fork,
|
||||
> or the Calibre content server. This instance still runs on a pinned image
|
||||
> tag; see below.
|
||||
|
||||
Readarr manages ebooks and audiobooks in the *arr stack. The stack runs on
|
||||
**FrankBook-Pro** (the Mac mini) as quadlet units inside its podman machine —
|
||||
not on Dankserver. It organizes books into the Calibre library that
|
||||
[[Calibre-Web]] serves.
|
||||
|
||||
**Host:** FrankBook-Pro (podman machine) — **Access:** direct port `8787` (no reverse-proxy vhost; the *arr stack is exempt by construction from the Anubis guard chain) — **Docs:** https://wiki.servarr.com/readarr
|
||||
|
||||
## Facts
|
||||
|
||||
| Item | Value |
|
||||
|------|-------|
|
||||
| Image | `lscr.io/linuxserver/readarr:amd64-1.0.980` — **pinned tag** (LSIO ships no untagged `latest` for readarr; the tag was pinned after a manifest probe) |
|
||||
| Port | 8787 (host) → 8787 (container) |
|
||||
| Env | `PUID=0`, `PGID=0`, `TZ=America/Los_Angeles`, `UMASK_SET=022` |
|
||||
| Config root | `/Volumes/COMPLETE/readarr-data:/config` |
|
||||
| Min RAM | 256 MB |
|
||||
| Metadata | Goodreads / StoryGraph (provider status at retirement) |
|
||||
|
||||
## Deployment (current)
|
||||
|
||||
Quadlet unit `readarr.container` from this repo (`frankbook-pro/readarr/quadlet/`)
|
||||
is installed inside the podman machine at
|
||||
`/home/core/.config/containers/systemd/readarr.service` by the frankbook-pro
|
||||
handler in `scripts/deploy-remote.sh`. Unit shape:
|
||||
|
||||
```ini
|
||||
[Container]
|
||||
ContainerName=readarr
|
||||
Image=lscr.io/linuxserver/readarr:amd64-1.0.980
|
||||
Environment=PUID=0
|
||||
Environment=PGID=0
|
||||
Environment=TZ=America/Los_Angeles
|
||||
Environment=UMASK_SET=022
|
||||
Volume=/Volumes/COMPLETE/readarr-data:/config
|
||||
PublishPort=8787:8787
|
||||
|
||||
[Service]
|
||||
TimeoutStartSec=900
|
||||
Restart=always
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
1. Add Prowlarr as the indexer source (torrent indexers with book content;
|
||||
the Byrutor row feeds Readarr — see [[Prowlarr]]).
|
||||
2. The qBittorrent download client is **parked**: Readarr's abandoned client
|
||||
fails auth against newer qB Web-API versions (see [[qBittorrent]] for the
|
||||
4.6.7 pin rationale); re-enable only after the image changes. Until then,
|
||||
books are imported manually or via Calibre tooling.
|
||||
3. Set author profile (format preference: epub, mobi, etc.).
|
||||
4. Set quality profile for audiobooks (320 kbps MP3, 128 kbps, lossless).
|
||||
5. Set the root folder to the books root under the COMPLETE volume.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- Readarr is abandoned upstream (retired May 2026; last line was 0.4.x before
|
||||
the final tags). The pinned `amd64-1.0.980` tag exists precisely because
|
||||
`:latest` does not exist for this image on LSIO.
|
||||
- Calibre integration is folder-based, not API-based. Readarr drops files into
|
||||
the books root which [[Calibre-Web]] serves.
|
||||
- Not all indexers carry all formats (epub, mobi, pdf). Goodreads/StoryGraph
|
||||
metadata helps match editions while those providers still respond.
|
||||
|
||||
## See Also
|
||||
|
||||
- [[ARR-Stack]] — full *arr stack documentation
|
||||
- [[Calibre-Web]] — ebook web frontend that serves Readarr downloads
|
||||
@@ -1,76 +0,0 @@
|
||||
---
|
||||
type: reference
|
||||
title: Sonarr
|
||||
description: Sonarr TV manager in the *arr stack on FrankBook-Pro — live quadlet deployment, ports, volumes, and wiring facts.
|
||||
tags: [sonarr, arr-stack, frankbook-pro]
|
||||
timestamp: 2026-09-04T00:00:00Z
|
||||
---
|
||||
|
||||
# Sonarr
|
||||
|
||||
Sonarr manages TV shows in the *arr stack. The stack runs on **FrankBook-Pro**
|
||||
(the Mac mini) as quadlet units inside its podman machine — not on Dankserver.
|
||||
It searches, downloads, and organizes episodes from indexers into the Jellyfin
|
||||
TV library.
|
||||
|
||||
**Host:** FrankBook-Pro (podman machine) — **Access:** LAN-direct only at
|
||||
`http://192.168.0.112:8989` — no vhost and no public DNS record by construction
|
||||
(the brief unguarded `sonarr.franksdank.cloud` vhost was retired 2026-09-04;
|
||||
users request TV via [[Seerr]], admins use this UI from the LAN) —
|
||||
**Docs:** https://wiki.servarr.com/sonarr
|
||||
|
||||
## Facts
|
||||
|
||||
| Item | Value |
|
||||
|------|-------|
|
||||
| Image | `lscr.io/linuxserver/sonarr:latest` (v4 line) |
|
||||
| Port | 8989 (host) → 8989 (container) |
|
||||
| Env | `PUID=0`, `PGID=0`, `TZ=America/Los_Angeles`, `UMASK_SET=022` |
|
||||
| Config root | `/Volumes/COMPLETE/sonarr-data:/config` |
|
||||
| Min RAM | 512 MB |
|
||||
| Metadata | TMDB / TVDB |
|
||||
|
||||
## Deployment (current)
|
||||
|
||||
Quadlet unit `sonarr.container` from this repo (`frankbook-pro/sonarr/quadlet/`)
|
||||
is installed inside the podman machine at
|
||||
`/home/core/.config/containers/systemd/sonarr.service` by the frankbook-pro
|
||||
handler in `scripts/deploy-remote.sh`. Unit shape:
|
||||
|
||||
```ini
|
||||
[Container]
|
||||
ContainerName=sonarr
|
||||
Image=lscr.io/linuxserver/sonarr:latest
|
||||
Environment=PUID=0
|
||||
Environment=PGID=0
|
||||
Environment=TZ=America/Los_Angeles
|
||||
Environment=UMASK_SET=022
|
||||
Volume=/Volumes/COMPLETE/sonarr-data:/config
|
||||
PublishPort=8989:8989
|
||||
|
||||
[Service]
|
||||
TimeoutStartSec=900
|
||||
Restart=always
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
1. Add Prowlarr as the indexer source (see [[Prowlarr]] — the feed route is `/{indexerId}/api`).
|
||||
2. Add qBittorrent as the download client with the `tv` category ([[qBittorrent]]).
|
||||
3. Set quality profile, cutoff, and minimum/maximum episode sizes.
|
||||
4. Set the root folder to the TV root under the COMPLETE volume (Sonarr imports
|
||||
from where [[qBittorrent]] drops completed downloads).
|
||||
5. Add a test series and verify the grab → download → import chain end-to-end.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- Sonarr v4 is the current stable. The v3 branch uses the `:v3` tag.
|
||||
- Anime has different quality profiles and naming conventions than Standard series.
|
||||
- Missing episodes: set "Unmonitor Missing Episodes" to auto-unmonitor old episodes.
|
||||
- Timezone-sensitive scheduler: every unit in the stack runs
|
||||
`TZ=America/Los_Angeles`; keep them uniform.
|
||||
|
||||
## See Also
|
||||
|
||||
- [[ARR-Stack]] — full *arr stack documentation
|
||||
- [[Jellyfin]] — media server that consumes Sonarr downloads
|
||||
Reference in New Issue
Block a user