First Services got Jellyfin running against whatever you manually dropped into its media folder. This page automates the finding, fetching, and organizing part, now that Centralized Storage gives that library somewhere sensible to actually live.

The pieces and how they connect

  • Prowlarr - manages indexers (sources Sonarr/Radarr search for content) in one place, and pushes that configuration out to the other apps automatically instead of configuring indexers three times over.
  • Sonarr - watches for TV shows you want, searches indexers via Prowlarr, sends matches to a download client, then renames and moves the finished files into your library.
  • Radarr - the same job, for movies. Same app, same pattern, separate instance.
  • A download client (qBittorrent is the common default) - does the actual downloading; Sonarr/Radarr just hand it jobs and poll for completion.
  • Jellyfin - already running from Beginner, watching the library folder these apps organize into.

Data flows one direction: Prowlarr configures indexers → Sonarr/Radarr search and queue → download client fetches → Sonarr/Radarr rename and move into the library → Jellyfin picks it up.

Running Prowlarr and Sonarr

services:
  prowlarr:
    image: lscr.io/linuxserver/prowlarr:latest
    container_name: prowlarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/London
    volumes:
      - ./prowlarr-config:/config
    ports:
      - "9696:9696"
    restart: unless-stopped

  sonarr:
    image: lscr.io/linuxserver/sonarr:latest
    container_name: sonarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/London
    volumes:
      - ./sonarr-config:/config
      - media:/media
      - downloads:/downloads
    ports:
      - "8989:8989"
    restart: unless-stopped

volumes:
  media:
    driver_opts:
      type: nfs
      o: addr=192.168.20.20,rw
      device: ":/mnt/tank/media"
  downloads:
    driver_opts:
      type: nfs
      o: addr=192.168.20.20,rw
      device: ":/mnt/tank/downloads"

Radarr is the identical pattern - same image family, its own config volume and port (7878). Add it once Sonarr feels comfortable rather than standing up all three at once.

Resource expectations: Prowlarr, Sonarr, and Radarr are all lightweight - well under 512MB RAM each, negligible CPU except during a library scan. The download client is I/O- and bandwidth-bound rather than CPU-bound.

Put downloads and the library on the same filesystem

Sonarr/Radarr move a finished download into your library by hardlinking (an instant, zero-copy filesystem operation) rather than copying, but only if /downloads and /media are on the same underlying filesystem - which is why both are mounted from the same NAS above rather than one being local and one being network storage. Split them across two different filesystems and every "move" silently becomes a slow, disk-filling copy instead.

The download client needs a VPN in front of it

If your download client is a torrent client (as most are for this stack), its traffic identifies your home IP directly to every peer it connects to, and to the tracker - not private the way browsing traffic is. Route qBittorrent's network traffic through a VPN container like Gluetun, so the download client has no path to the internet except through the tunnel:

services:
  gluetun:
    image: qmcgaw/gluetun:latest
    container_name: gluetun
    cap_add:
      - NET_ADMIN
    environment:
      - VPN_SERVICE_PROVIDER=your-provider
      - VPN_TYPE=wireguard
      - WIREGUARD_PRIVATE_KEY=${WG_PRIVATE_KEY}
    ports:
      - "8080:8080"
    restart: unless-stopped

  qbittorrent:
    image: lscr.io/linuxserver/qbittorrent:latest
    container_name: qbittorrent
    network_mode: "service:gluetun"
    environment:
      - PUID=1000
      - PGID=1000
    volumes:
      - ./qbittorrent-config:/config
      - downloads:/downloads
    depends_on:
      - gluetun
    restart: unless-stopped

network_mode: "service:gluetun" gives qBittorrent no network interface of its own at all - every packet it sends goes through Gluetun's tunnel, and if the tunnel drops, qBittorrent simply loses connectivity rather than falling back to your real IP. That fail-closed behavior is the entire point; a VPN client that fails open defeats the purpose.

⚠️ Risk: what you point this stack at is entirely your call, and the legal picture varies by content, provider terms, and region - that's on you to know, not something this guide can settle generically. The VPN and networking setup above is worth doing regardless of what you're downloading, for the same reason you wouldn't want your home IP directly visible to arbitrary peers under any circumstances.

Backing it up

The arr apps' config folders (small SQLite databases holding your library state, indexer config, and quality settings) are worth including in your regular backup scope - see Proxmox Backups. The media library itself is usually the one exception worth naming explicitly: most homelabbers treat it as re-acquirable rather than backup-critical, unlike the photo library from Immich in Beginner, which isn't. Decide which category your library actually falls into rather than assuming.

Next: GPU Passthrough and Hardware Transcoding.