Jellyfin - Setting up the entire stack¶
This post will guide you to setting up your own Jellyfin *arr stack with VPN. That means an automated pipeline and the privacy of proton vpn. If you want the full Proton experience, check out Proton Pass.
Step 1: Setting up Jellyfin¶
The easy part. Let's go ahead and set up Jellyfin. If you have a movie file already, this as great time to go ahead and test the indexing of Jellyfin.
jellyfin:
image: jellyfin/jellyfin
container_name: jellyfin
restart: unless-stopped
volumes:
- ./jellyfin-config:/config
- /mnt/md0/apps/jellyfin/media:/media
ports:
- 8700:8096
devices:
- /dev/dri:/dev/dri # For hardware acceleration (Intel/AMD)
environment:
- TZ=America/Denver
I only changed the mapped port because I'm already using 8096.
Note
When creating your jellyfin library, I created a separate media and downloads folder. Inside of media, go ahead and create folders for audiobooks, movies, music, tv, etc. Whatever types of media you have.
In the Dashboard settings in JellyFin, add whatever libraries you want Jellyfin to pickup, i.e. Movies, Shows. The folder should be /media/movies, or /media/tv.
Setting up the Stack and VPN¶
Now that we understand the Jellyfin bind mounts, let's go ahead and add the entire *arr stack along with gluetun and qBitTorrent.
docker-compose.yml
services:
jellyfin:
image: jellyfin/jellyfin
container_name: jellyfin
user: 1000:1000
ports:
- 8096:8096/tcp
# - 7359:7359/udp
volumes:
- ./jellyfin-config:/config
- ./jellyfin-cache:/cache
- ${DATA_LOCATION}:/data
restart: 'unless-stopped'
environment:
- TZ=${TIMEZONE}
- /dev/dri:/dev/dri
gluetun:
image: qmcgaw/gluetun
container_name: gluetun
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun
ports: # Expose qBittorrent's web UI and torrent ports through VPN
# - 8700:8096 # Jellyfin
- 8701:8701 # qBittorrent Web UI
- 6881:6881 # torrent port
- 6881:6881/udp
- 7878:7878 # Radarr
- 8989:8989 # Sonarr
- 8686:8686 # Lidarr
- 6767:6767 # Bazarr
- 9696:9696 # Prowlarr
- 8191:8191 # FlareSolverr
# - 5055:5055 # Jellyseerr
volumes:
- ./gluetun:/gluetun
# - ./gluetun/us-den.conf:/gluetun/wireguard/wg0.conf
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}
qbittorrent:
image: lscr.io/linuxserver/qbittorrent
container_name: qbittorrent
network_mode: "service:gluetun" # Routes all traffic through Gluetun
depends_on:
- gluetun
environment:
- PUID=1000
- PGID=1000
- TZ=${TIMEZONE}
- WEBUI_PORT=8701
- WEBUI_ADDRESS=0.0.0.0
- WEBUI_EXTERNAL_ACCESS=true
volumes:
- ./qbittorrent:/config
- ${DATA_LOCATION}:/data
restart: unless-stopped
radarr:
image: lscr.io/linuxserver/radarr
container_name: radarr
restart: unless-stopped
network_mode: "service:gluetun" # Routes all traffic through Gluetun
depends_on:
- gluetun
# ports:
# - 7878:7878
environment:
- PUID=1000
- PGID=1000
- TZ=${TIMEZONE}
volumes:
- ./radarr:/config
- ${DATA_LOCATION}:/data
sonarr:
image: lscr.io/linuxserver/sonarr
container_name: sonarr
restart: unless-stopped
network_mode: "service:gluetun" # Routes all traffic through Gluetun
depends_on:
- gluetun
# ports:
# - 8989:8989
environment:
- PUID=1000
- PGID=1000
- TZ=${TIMEZONE}
volumes:
- ./sonarr:/config
- ${DATA_LOCATION}:/data
lidarr:
image: lscr.io/linuxserver/lidarr:latest
container_name: lidarr
network_mode: "service:gluetun" # Routes all traffic through Gluetun
depends_on:
- gluetun
# ports:
# - 8686:8686
environment:
- PUID=1000
- PGID=1000
- TZ=${TIMEZONE}
volumes:
- ./lidarr:/config
- ${DATA_LOCATION}:/data
restart: unless-stopped
bazarr:
image: lscr.io/linuxserver/bazarr
container_name: bazarr
restart: unless-stopped
network_mode: "service:gluetun" # Routes all traffic through Gluetun
depends_on:
- gluetun
# ports:
# - 6767:6767
environment:
- PUID=1000
- PGID=1000
- TZ=${TIMEZONE}
volumes:
- ./bazarr:/config
- ${DATA_LOCATION}:/data
prowlarr:
image: lscr.io/linuxserver/prowlarr
container_name: prowlarr
restart: unless-stopped
network_mode: "service:gluetun" # Routes all traffic through Gluetun
depends_on:
- gluetun
# ports:
# - 9696:9696
environment:
- PUID=1000
- PGID=1000
- TZ=${TIMEZONE}
volumes:
- ./prowlarr:/config
flaresolverr:
image: ghcr.io/flaresolverr/flaresolverr:latest
container_name: flaresolverr
network_mode: "service:gluetun" # Routes all traffic through Gluetun
environment:
- TZ=${TIMEZONE}
depends_on:
- gluetun
# ports:
# - 8191:8191
restart: unless-stopped
jellyseerr:
image: fallenbagel/jellyseerr:latest
container_name: jellyseerr
environment:
- TZ=${TIMEZONE}
- LOG_LEVEL=info
ports:
- "5055:5055"
volumes:
- ./jellyseerr:/app/config
restart: unless-stopped
depends_on:
- gluetun
- jellyfin
- sonarr
- radarr
So in the .env we have the media location, download location, and timezone like so
DATA_LOCATION=/mnt/md0/apps/jellyfin/data
TIMEZONE=America/Denver
OPENVPN_USER=
OPENVPN_PASSWORD=
The port forwarding only works using the OpenVPN method. You can find the values for your OPENVPN_USER and OPENVPN_PASSWORD by navigating to https://account.proton.me/u/0/vpn/OpenVpnIKEv2.
You can now take the entire stack up.
Go ahead and check the health of your stack, particularly the Gluetun container. In the logs, you should see something like the following:
At this point, you can also try a quick curl command from within the qbittorrent container to make sure the IP address of that container is indeed the same.
Setting up qBitTorrent¶
Before Radarr or Sonarr can send any jobs to qBitTorrent, we need to configure qBitTorrent.
qBitTorrent seems to be the one service that does need to be connected to with https when connecting from outside of your server. Set up a reverse proxy and DNS entry to access qBitTorrent over https.
To login the first time, check the docker logs which should provide a username and password. Otherwise, try admin and adminadmin.
Now is another time for a sanity check to make sure qBitTorrent is indeed using the VPN. Head to https://ipleak.net/ and go to Torrent Address detection. Click on Activate and right click and copy the Magnent Link. Then in qBitTorrent, add a Torrent from a link and paste that in. Back on ipleak.net it should show a connection from your VPN IP address. If that's the case, you're good to go.
Set up download directories¶
Go to Tools -> Options -> Downloads
Make sure that the Default save path is /downloads.
Whatever sub folders you created in your jellyfin bind mount, let's create categories for each of these. This way each of our services that send jobs to qBitTorrent can include a category and that way jellyfin indexes it properly. On the left menu, expand Categories, right click on All, and choose Add category...
For movies, set the save path to downloads/movies. Go ahead and do this music, tv, audiobooks.
Setting up Prowlarr¶
Prowlarr is a tracking container, it's needs by each of the *arr services to find an appropriate tracker for media and send it to qBitTorrent.
Before we add an Indexer, let's go ahead and set up a connection to flaresolverr. This will be needed for some of the Indexers that area behind Cloudflare bot detection. Go to Settings -> Indexers. Click the + button and choose FlareSolverr. You shold be able to set the host to http://localhost:8191/. Set the tag to cloudflare. Test the connection and save.
Let's go ahead and add an Indexer. 1337x tends to be quite reliable. If the indexer requires the flaresolverr just make sure to add the cloudflare tag to the indexer, then test the connection.
Note that the other *arr apps will want an api key to talk to Prowlarr. This will be located in Settings -> General -> Security -> API Key. Likewise, for reverse communication, you can generate keys in each of the *arr apps and add each app to Settings -> Apps. If you do the latter, than Indexers will automatically be added to your *arr apps which I prefer.
Setting up Radarr¶
First set the root folder in Media Management. Click the add root folder, and set it to /media/movies. I'd go ahead and set it to rename movies too so that it's standardized.
Connecting to Prowlar for Auto-Sync¶
Head over to your Radarr web app. We need to set up the connection to both qBitTorrent and Prowlarr. Following up on the previous section, make sure you go get Radarr's api key and add Radarr as an app in Prowlarr. So inside Prowlarr, hit the plus button to add an app. Call it Radarr, sync level Full Sync, Prowlarr server should be http://localhost:9696, Radarr server should be set to http://localhost:7878. Add the api key from Radarr and make sure the sync categories are set to Movies and whatever subcategories. This way only movie trackers will get synced to Radarr.
In Radarr we should now see any Indexers we added in Prowlarr.
Connecting to qBitTorrent¶
Now go to Settings -> Download Clients, click the plus sign and add qBittorrent. The host can be set to localhost and port set to 8080 (remember, these are all internally connected on the same network). Use your qBittorrent Username and Password. Set the category to movies.
You are now ready to download a movie in the Movies section! When you download a movie, check your qBittorrent and make sure the donwloading is working. If you see the status as Halted, then it's likely that the port forwarding configuration did not work with your VPN.
Sonarr Setup¶
Ok, this will be pretty identical to setting up Radaar. Let's go to Media Management, allow it to rename episodes, and set the root folder to /media/tv.
Add the qBitTorrent client. Set the category to tv.
Go get the API key (Settings -> General -> API Key), then go to Prowlaar and add Sonarr as an app in Settings -> Apps.