Skip to content

Jellyfin + the *arr Stack

TL;DR / when to use this: Jellyfin as the media server with an automated *arr pipeline (Radarr/Sonarr/Lidarr/Bazarr/Prowlarr), qBittorrent as the download client, and Gluetun routing every torrent through a VPN. The pattern that matters: *all arr containers share Gluetun's network via network_mode: "service:gluetun" — only Gluetun exposes ports, so nothing leaks outside the VPN.

Jellyfin

jellyfin:
  image: jellyfin/jellyfin
  container_name: jellyfin
  restart: unless-stopped
  volumes:
    - ./jellyfin-config:/config
    - /mnt/md0/apps/jellyfin/media:/media
  ports:
    - 8700:8096          # remapped if 8096 is taken
  devices:
    - /dev/dri:/dev/dri  # hardware acceleration (Intel/AMD)
  environment:
    - TZ=America/Denver

Library layout: separate media and downloads folders; inside media, per-type folders (movies, tv, music, audiobooks). Add each as a library in the Jellyfin dashboard pointing at /media/movies, /media/tv, etc.

The stack

Every *arr app + qBittorrent + FlareSolverr runs with network_mode: "service:gluetun", so their traffic exits through the VPN. Ports are exposed on Gluetun only:

gluetun:
  image: qmcgaw/gluetun
  container_name: gluetun
  cap_add:
    - NET_ADMIN
  devices:
    - /dev/net/tun
  ports:
    - 8701:8701    # qBittorrent web UI
    - 6881:6881    # torrent port (tcp + udp)
    - 7878:7878    # Radarr
    - 8989:8989    # Sonarr
    - 8686:8686    # Lidarr
    - 6767:6767    # Bazarr
    - 9696:9696    # Prowlarr
    - 8191:8191    # FlareSolverr
  volumes:
    - ./gluetun:/gluetun
  environment:
    - VPN_TYPE=openvpn
    - VPN_SERVICE_PROVIDER=protonvpn
    - OPENVPN_USER=${OPENVPN_USER}
    - OPENVPN_PASSWORD=${OPENVPN_PASSWORD}
    - VPN_PORT_FORWARDING=on
    - SERVER_COUNTRIES=United States
    - TZ=${TIMEZONE}

Each *arr service is the standard lscr.io/linuxserver/<app> image with network_mode: "service:gluetun", depends_on: gluetun, a ./<app>:/config volume, and the shared ${DATA_LOCATION}:/data mount (qBittorrent downloads land in /data, the *arrs import from the same path). FlareSolverr handles indexers behind Cloudflare.

Wiring: Prowlarr grants each *arr app an API key and syncs indexers; each *arr points its download client at qBittorrent (reachable through Gluetun's network); Jellyfin watches the media folders.

Notifications

The *arr apps notify through Gotify/Apprise — see Notifications.

See also