Media Stack

Home

Services running on PCT 102 (media-core, 192.168.2.191). Stack: media-core (compose 26).


Service URLs

Service URL Port
Jellyfin jellyfin.carr-family.org 8096 (standalone, static route)
Sonarr sonarr.carr-family.org 8989
Radarr radarr.carr-family.org 7878
Prowlarr prowlarr.carr-family.org 9696
Jellyseerr seerr.carr-family.org 5055
Calibre-Web Automated book.carr-family.org 8083
Audiobookshelf audiobook.carr-family.org 13378
Audiobookrequest abr.carr-family.org 8000
Shelfmark shelfmark.carr-family.org 8084
OpenBooks openbooks.carr-family.org 8875
Komga komga.carr-family.org 25600
RomM romm.carr-family.org 8984

Storage Layout

Path Contents
/mnt/tank/media/content/movies Movies
/mnt/tank/media/content/tv TV shows
/mnt/tank/media/content/books Calibre library (managed by CWA — don't move files manually)
/mnt/tank/media/content/books-seeds MAM torrent seeding copies (never touch)
/mnt/tank/media/content/audiobooks Audiobookshelf + Shelfmark audiobook downloads
/mnt/tank/media/content/comics Komga library
/mnt/tank/media/content/roms RomM ROM library (organize by platform subfolder)
/mnt/tank/media/bookingest CWA ingest folder + Shelfmark ebook downloads

Calibre-Web Automated (CWA)

Volumes: /mnt/tank/media/bookingest:/cwa-book-ingest, /mnt/tank/media/content/books:/calibre-library

Config: NETWORK_SHARE_MODE=true, CWA_WATCH_MODE=poll

Ingest mount gotcha — verify mount with docker inspect <container> | grep Mounts. If CWA sees an empty ingest folder, the compose may have been updated without a redeploy.

root:root ownership breaks deletes — CWA web server runs as abc (uid 1000) but ingest processor runs as root with NETWORK_SHARE_MODE=true which skips the post-import chown. Files land as root:root and deletes fail with [Errno 13]. Fix: chown -R 1000:1000 /tank/media/content/books.

Bulk-delete always shows success (CWA bug) — the /ajax/deleteselectedbooks route always returns {"success": true}. Check container logs for Deleting book X failed if books reappear.

Don't bulk-delete duplicates while ingest is running — wait for all imports to complete first.

Calibre Email Setup

  • SMTP hostname: 192.168.2.83 (Proton Bridge)
  • Port: 1025, Encryption: None
  • Login: [email protected], Password: 8A2SC9qao04GsSqBrfjtFg

calibredb Commands

# Get CWA container name
pct exec 102 -- docker ps --format '{{.Names}}' | grep calibre

# List all books as JSON
pct exec 102 -- docker exec <cwa-container> calibredb list \
  --fields=id,title,authors,series,series_index,tags --sort-by=title \
  -s '' --library-path=/calibre-library --for-machine

# Remove by ID
pct exec 102 -- docker exec <cwa-container> calibredb remove \
  --library-path=/calibre-library <id1>,<id2>

Shelfmark

Book search & request tool. Config: /mnt/tank/appdata/shelfmark/plugins/.

After any config edit: pct exec 108 -- docker service update --force media-core_shelfmark

  • qBittorrent connection: 192.168.2.190:8080, creds admin / 32Ab0321!!
  • Ebook category: books-shelfmark, Audiobook category: audiobooks
  • Remote path mappings (advanced.json) — must use camelCase keys and host: "qbittorrent":
[
  {"host": "qbittorrent", "remotePath": "/data/bookingest", "localPath": "/books"},
  {"host": "qbittorrent", "remotePath": "/data/content/audiobooks", "localPath": "/audiobooks"}
]

Komga

Comics & manga at komga.carr-family.org. Library: /mnt/tank/media/content/comics.

CONVERT_TO_CBZ=false, REPAIR_EXTENSIONS=false — do not re-enable (was renaming .cbr → .cbz, breaking seeding).


RomM (compose 32)

ROM manager with in-browser EmulatorJS at romm.carr-family.org. Port 8984, host-mode on 192.168.2.191. Auth: RomM built-in (no Authentik — would break EmulatorJS API calls).

  • ROMs: /mnt/tank/media/content/roms:/romm/library — organize by platform subfolder
  • Config: /mnt/tank/appdata/romm/config/config.yml — must exist before first start
  • Metadata: IGDB (u5audru2zn9na5a0x3wq26yslmk1s5) + RetroAchievements configured in compose env
pct exec 108 -- docker stack deploy -c /mnt/tank/appdata/portainer/compose/32/docker-compose.yml romm

Jellyfin (PCT 101 — standalone, not Swarm)

Media server at jellyfin.carr-family.org. Static route in routes.yml192.168.2.191:8096.


FlareSolverr

Internal only (192.168.2.191:8191). Cloudflare bypass for Prowlarr indexers.