No description
Find a file
Bob Parsons 9bd3fd81eb
All checks were successful
Deploy / deploy (push) Successful in 39s
fixed all the images
2026-03-23 20:52:06 -05:00
.gitea/workflows add lidarr 2026-03-07 16:02:57 -06:00
.env.example remove headphones and pin version 2026-03-22 07:44:33 -05:00
.gitignore init commit 2026-03-07 08:07:31 -06:00
docker-compose.yml fixed all the images 2026-03-23 20:52:06 -05:00
README.md remove headphones and pin version 2026-03-22 07:44:33 -05:00

watchlist

Automated media stack for Jellyfin, deployed separately from Jellyfin itself.

Services in this project:

  • gluetun (ProtonVPN WireGuard gateway)
  • qbittorrent (torrent download client)
  • sabnzbd (usenet download client)
  • prowlarr (indexer manager)
  • sonarr (TV)
  • radarr (movies)
  • lidarr (music)
  • whisparr (adult)
  • seerr (request UI for users)

Architecture

  • VPN-routed services (through gluetun): qbittorrent, sabnzbd, sonarr, radarr, lidarr, whisparr
  • Non-VPN services: prowlarr, seerr
  • Shared media/download storage: host ${MEDIA_ROOT} mounted as /data in media containers
  • Jellyfin stays separate, only reads the library directories

This keeps playback stable even if VPN or automation services fail.

Prerequisites

  • Docker + Docker Compose installed
  • Existing Traefik network named traefik (or create it)
  • ProtonVPN WireGuard config values:
    • WIREGUARD_PRIVATE_KEY
    • WIREGUARD_ADDRESSES

Directory Layout

Default MEDIA_ROOT is /mnt/nas-direct.

Expected structure:

  • media/library/movies
  • media/library/tv
  • media/library/music
  • media/library/adult
  • media/rips/movies
  • media/rips/tv
  • downloads/torrents/incomplete
  • downloads/torrents/complete
  • downloads/usenet/incomplete
  • downloads/usenet/complete

Create it:

mkdir -p \
  /mnt/nas-direct/media/library/movies \
  /mnt/nas-direct/media/library/tv \
  /mnt/nas-direct/media/library/music \
  /mnt/nas-direct/media/library/adult \
  /mnt/nas-direct/media/rips/movies \
  /mnt/nas-direct/media/rips/tv \
  /mnt/nas-direct/downloads/torrents/incomplete \
  /mnt/nas-direct/downloads/torrents/complete \
  /mnt/nas-direct/downloads/usenet/incomplete \
  /mnt/nas-direct/downloads/usenet/complete

Configuration

  1. Copy env template:
cp .env.example .env
  1. Fill required values in .env:
  • WIREGUARD_PRIVATE_KEY
  • WIREGUARD_ADDRESSES
  1. Optional VPN filtering:
  • SERVER_COUNTRIES=United States
  • SERVER_CITIES= (blank is usually best initially)
  1. Optional LAN allow-list from VPN containers:
  • FIREWALL_OUTBOUND_SUBNETS=192.168.1.0/24

Use only if VPN-contained apps must call LAN IPs.

Deploy

cd /home/bobparsons/Development/watchlist
docker network inspect traefik >/dev/null 2>&1 || docker network create traefik
docker compose -p watchlist pull
docker compose -p watchlist up -d --remove-orphans
docker compose -p watchlist ps

Service URLs

  • Seerr: https://${SEERR_DOMAIN}
  • Prowlarr: http://<host-ip>:9696
  • Sonarr: http://<host-ip>:8989
  • Radarr: http://<host-ip>:7878
  • Lidarr: http://<host-ip>:8686
  • Whisparr: http://<host-ip>:6969
  • SABnzbd: http://<host-ip>:8085
  • qBittorrent: http://<host-ip>:8080

First-Time App Wiring

1) Download clients in Sonarr/Radarr/Lidarr/Whisparr

Add SABnzbd:

  • Host: localhost
  • Port: 8085
  • Categories:
    • Sonarr: tv
    • Radarr: movies
    • Lidarr: music
    • Whisparr: adult

(Optional) Add qBittorrent:

  • Host: localhost
  • Port: 8080
  • Matching categories if you use torrents

2) Root folders

Use container paths:

  • Sonarr: /data/media/library/tv
  • Radarr: /data/media/library/movies
  • Lidarr: /data/media/library/music
  • Whisparr: /data/media/library/adult

Enable hardlinks where available in Media Management.

3) Prowlarr

  • Add indexers you have access to (e.g. NZBGeek)
  • Add Applications:
    • Sonarr: http://gluetun:8989
    • Radarr: http://gluetun:7878
    • Lidarr: http://gluetun:8686
    • Whisparr: http://gluetun:6969
  • Use each app's API key

4) Seerr

  • Connect to Jellyfin
  • Add Sonarr and Radarr in Seerr using:
    • Sonarr: http://gluetun:8989
    • Radarr: http://gluetun:7878

Jellyfin Integration

In Jellyfin, mount and libraries should remain read-only:

  • Mount: /mnt/nas-direct/media:/media:ro
  • Libraries:
    • /media/library/movies
    • /media/library/tv
    • /media/library/music (optional)

Keep manual rips under /media/rips/* as separate staging/input paths.

Operational Checks

Verify VPN routing

curl -s https://api.ipify.org && echo
docker exec media-radarr sh -lc 'curl -s https://api.ipify.org && echo'

Host IP and container IP should differ if VPN routing is active.

Common useful commands

docker compose -p watchlist logs -f gluetun
docker compose -p watchlist logs -f radarr
docker compose -p watchlist logs -f sonarr
docker compose -p watchlist ps

Common Issues

  • Download client unavailable

    • Verify SAB/qB is added with localhost inside Arr app.
  • No indexers available

    • Check Prowlarr indexer test results.
    • Re-sync app indexers from Prowlarr.
  • The /app/config volume mount was not configured properly in Seerr

    • Ensure named volume seerr-config is mounted.
  • Gluetun unhealthy

    • Start with SERVER_COUNTRIES=United States and blank SERVER_CITIES.
    • Confirm WireGuard values are correct.

Updating

cd /home/bobparsons/Development/watchlist
docker compose -p watchlist pull
docker compose -p watchlist up -d --remove-orphans
docker image prune -f