Files
docudjeex/content/en/3.serveex/5.media/3.servarr.md
T

19 KiB
Raw Blame History

title, description
title description
Automation Automate media downloads with the Servarr stack, Radarr, Sonarr, Bazarr, Prowlarr, and Seerr, for movies and TV shows.

:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}

Servarr is a suite of applications developed to automate the downloading, updating, and management of media. Here, we'll focus on movies and TV shows with the goal of:

  • Selecting a movie from a catalog through a web interface.
  • Sitting back and enjoying it on Jellyfin a few minutes later.

Simple.

arr

Well start by deploying the stack and then proceed to configure each app and understand how they work.

Install the Apps

::file-tree

tree: /: - docker: - jellyfin: - compose.yml - .env - config/ - sonarr: - config/ - radarr: - config/ - bazarr: - config/ - prowlarr: - config/ - seerr: - config/ - media: - downloads/ - tvseries/ - movies/ - library/

::

::warning

Warning: Make sure to follow this file structure carefully, especially the media folder. This folder must be mounted exactly the same way in both the Qbittorrent compose file (/your/path/media:/media) and the arr applications. If not, the arr apps may not recognize the path provided by Qbittorrent and will fail to create hardlinks. Without hardlinks, the arr apps will copy the files instead, doubling the space used on your storage. ::

::steps{level="3"}

Deploy the stack

Open Docker and your jellyfin stack. Modify the compose file as follows:

---
services:
  jellyfin:
    image: lscr.io/linuxserver/jellyfin:latest
    container_name: jellyfin
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=Europe/Paris
    volumes:
      - /docker/jellyfin/config:/config
      - ${MEDIA_PATH}:/media
    restart: unless-stopped
    devices:
      - /dev/dri:/dev/dri
    ports:
      - 8096:8096

  sonarr:
    image: lscr.io/linuxserver/sonarr:latest
    container_name: sonarr
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=Europe/Paris
    volumes:
      - /docker/sonarr/config:/config
      - ${MEDIA_PATH}:/media
    ports:
      - 8989:8989
    restart: unless-stopped

  radarr:
    image: lscr.io/linuxserver/radarr:latest
    container_name: radarr
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=Europe/Paris
    volumes:
      - /docker/radarr/config:/config
      - ${MEDIA_PATH}:/media
    ports:
      - 7878:7878
    restart: unless-stopped

  prowlarr:
    image: lscr.io/linuxserver/prowlarr:latest
    container_name: prowlarr
    environment:
      - PUID=${PUID}
      - PGID=${PGID}
      - TZ=Europe/Paris
    volumes:
      - /docker/prowlarr/data:/config
    ports:
      - 9696:9696
    restart: unless-stopped

  seerr:
    image: ghcr.io/seerr-team/seerr:latest
    container_name: seerr
    environment:
      - LOG_LEVEL=info
      - TZ=Europe/Paris
    volumes:
      - /docker/seerr/config:/app/config
    ports:
      - 5055:5055
    restart: unless-stopped

  bazarr:
    image: lscr.io/linuxserver/bazarr:latest
    container_name: bazarr
    restart: unless-stopped
    environment:
      - PUID=1000 
      - PGID=1000
      - TZ=Europe/Paris
    volumes:
      - /docker/bazarr/config:/config
      - ${MEDIA_PATH}:/media
    ports:
      - 6767:6767

::tip{icon=""} Add the Watchtower label to each container to automate updates

---
services:
  jellyfin:
    #...
    labels:
      - com.centurylinklabs.watchtower.enable=true

::

Set your environment variables

Set your .env file with the variables below:

PUID=
GUID=
MEDIA_PATH=
Variable Description Example
PUID Set using your user info (check with id yourusername) 1000
GUID Same as above 1000
MEDIA_PATH Path to your media folder, here: /media. It must match the one used by Qbittorrent. /media

::note

Unlike the other containers here, Seerr's image doesn't use PUID/PGID; it always runs as UID 1000. Make sure /docker/seerr/config is owned by that user, or Seerr won't be able to write to it:

sudo chown -R 1000:1000 /docker/seerr/config

::

Deploy the stack.

Done !

::

Configure Radarr

Radarr queries your torrent sources and lets you define the type of releases to prioritize. It can also upgrade your movies if a better version is available.

Once deployed, visit http://yourserverip:7878.

::caution

If it fails: check your firewall rules. ::

Create an account and choose forms login.

::steps{level="4"}

Add a root folder

  • Go to Settings > Media Management.
  • Add a root folder and select /media/movies.

::warning

Warning: If you already have movies in movies from Qbittorrent, do not let Radarr add them. Radarr might modify them, which could stop seeding in Qbittorrent. ::

Configure Profiles

Go to Settings > Profiles. These are your default quality profiles. When you make a request, you're selecting one of these. For example, configure the “any” profile by unchecking everything except what is shown in the image and ordering them accordingly. This makes Radarr search for 4K REMUX first, then go down the list if unavailable.

profiles_radarr

Add Qbittorrent

In Settings > Download Clients, add Qbittorrent.

  • Use your server IP as Host and port 5695 if following this guide.
  • Provide your Qbittorrent Username and Password.
  • Click Test.
  • If successful, click Save.

Connect to Jellyfin

First, get an API key from Jellyfin: log in as admin, go to Dashboard > Advanced > API Keys, and add a new one.

Then, in Radarr, go to Settings > Connect, add a new connection and choose Jellyfin.

  • Use jellyfin or your server IP for Host.
  • Port: 8096
  • Paste the API key you generated.
  • Press Test, then Save if successful.

Get API Key for Prowlarr and Seerr

  • Go to Settings > General and copy your API Key for later use.

Done !

::

Configure Sonarr

Sonarr queries torrent sources and defines what kind of TV series releases to prioritize. It also upgrades series when better versions are available.

  • Visit http://yourserverip:8989.
  • Follow the same steps as for Radarr, but use /media/tvseries as the root folder.

::caution

If it fails: check your firewall rules. ::

Configure Prowlarr

Prowlarr acts as a proxy to manage your torrent indexers and link them to Radarr and Sonarr.

Go to http://yourserverip:9696 and create an account, using forms login.

::caution

If it fails: check your firewall rules. ::

::steps{level="4"}

Add an Indexer

  • Go to the Indexers section and add your torrent indexer.

Add Radarr and Sonarr

In Settings > Apps, add Radarr and Sonarr with the following details:

  • Prowlarr Server: http://prowlarr:9696 (or use server IP)
  • Sonarr / Radarr Server: http://sonarr:8989 or http://radarr:7878
  • API Key: use the one copied from Radarr and Sonarr.
  • Click Test, then Save if all goes well.

Done !

::

Configuring Bazarr

Bazarr is an app that automatically searches for the correct subtitles in your preferred languages for all the movies and TV shows added by Radarr and Sonarr.

Go to http://yourserverip:6767.

::caution

If it fails: check your firewall rules. ::

Go to Settings > General and create a username and password using forms login.

::steps{level="4"}

Add a Language Profile

  • In Settings > Languages, click the pink Add new profile button and name it.

  • Click the pink Add Languages button and add your preferred languages, e.g., French and English.

  • Save and exit.

  • At the bottom of the screen under Default Language For Newly Added Show, check both boxes and select the profile you just created. Bazarr

  • Save using the button at the top of the screen.

Add Subtitle Providers

  • In Settings > Providers, add your preferred providers, for example:

Bazarr

  • Save using the button at the top of the screen.

Add Radarr and Sonarr

  • Go to Settings > Sonarr
  • In Address, enter sonarr or your server's IP address.
  • In Port, enter 8989.
  • In API Key, enter Sonarrs API key.
  • Click Test.
  • Save using the button at the top of the screen.

Repeat the same steps for Radarr.

Done !

::

Configuring Seerr

Seerr (the unified successor of Overseerr and Jellyseerr) is an app that lets you browse a movie catalog and send requests to Sonarr and Radarr. Just browse movies or series, click Request, and the media will automatically be downloaded according to your Radarr or Sonarr settings. If the title hasnt been released yet, it will be downloaded automatically when available. This way, episodes of a series appear in Jellyfin without any manual intervention.

Go to http://yourserverip:5055, select Jellyfin as your media server, and sign in with your Jellyfin admin account.

::caution

If it fails: check your firewall rules. ::

::steps{level="4"}

Add Radarr

When prompted, add a Radarr server:

  • Check Default server.
  • Server name: Radarr
  • Hostname or IP address: radarr or your server's IP
  • Port: 7878
  • API Key: Radarrs API key
  • Click Test at the bottom.

If the test succeeds, continue filling in the fields:

  • Quality Profile: the one you configured (e.g., any)
  • Root Folder: the Jellyfin folder. In our examples: /media/movies
  • Minimum Availability: Announced. This allows requesting unreleased content and downloads it upon release.
  • Check all 3 boxes at the bottom.
  • Save and continue.

Add Sonarr

Now do the same for Sonarr:

  • Check Default server.
  • Server name: Sonarr
  • Hostname or IP address: sonarr or your server's IP
  • Port: 8989
  • API Key: Sonarrs API key
  • Click Test at the bottom.

If the test succeeds, continue filling in the fields:

  • Quality Profile: the one you configured (e.g., any)
  • Root Folder: the Jellyfin folder. In our examples: /media/tvseries
  • Language Profile: Deprecated
  • Check all 4 boxes at the bottom.
  • Save and continue.

Done !

::

And thats it! Just request a movie or series, then check in qBittorrent or Radarr/Sonarr. Within a few minutes, your media will be available on Jellyfin!

Exposing Seerr with SWAG

It can be useful to expose Seerr if you want to send requests from outside your network without a VPN, or if you've shared your Jellyfin library with others and want them to have Seerr access.

::warning

Seerr has no built-in two-factor authentication. Only expose it if you're using a secure authentication solution like TinyAuth or Authentik. Otherwise, don't expose it with SWAG, use a VPN like Wireguard instead. ::

::note

We assume you have the subdomain films.mydomain.com with a CNAME pointing to films.fr in your DNS zone. And that unless youre using Cloudflare Zero Trust, port 443 on your router is forwarded to port 443 on your server via NAT rules. ::

::steps{level="3"}

Add Seerr's network to SWAG

Go to Dockge, edit the SWAG compose file, and add the Seerr network, which is the same as Jellyfin (since its in the Jellyfin stack):

---
services:
  swag:
     container_name: # ...
      # ... 
     networks:              # Connects the container to a custom network 
      # ...           
      - jellyfin            # Name of the network declared in the stack
    
networks:                   # Defines the custom network
  # ...
  jellyfin:                 # Name of the declared network
    name: jellyfin_default  # Actual name of the external network
    external: true          # Indicates its an external network

Restart the stack by clicking “Deploy” and wait until SWAG is fully operational.

::note

Here we assume the Jellyfin network is named jellyfin_default. You can verify the connection works by visiting the SWAG dashboard at http://yourserverip:81. ::

Create the subdomain.conf file

Create and edit the file films.subdomain.conf:

::tip{icon=""} Tip: you can use File Browser Quantum to browse and edit files instead of using terminal commands. ::

sudo nano /docker/swag/config/nginx/proxy-confs/films.subdomain.conf

Paste the following:

## Version 2024/07/16
# make sure that your seerr container is named seerr
# make sure that your dns has a cname set for seerr

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name films.*;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;

    # enable for ldap auth (requires ldap-location.conf in the location block)
    #include /config/nginx/ldap-server.conf;

    # enable for Authelia (requires authelia-location.conf in the location block)
    #include /config/nginx/authelia-server.conf;

    # enable for Authentik (requires authentik-location.conf in the location block)
    #include /config/nginx/authentik-server.conf;

    location / {
        # enable the next two lines for http auth
        #auth_basic "Restricted";
        #auth_basic_user_file /config/nginx/.htpasswd;

        # enable for ldap auth (requires ldap-server.conf in the server block)
        #include /config/nginx/ldap-location.conf;

        # enable for Authelia (requires authelia-server.conf in the server block)
        #include /config/nginx/authelia-location.conf;

        # enable for Authentik (requires authentik-server.conf in the server block)
        #include /config/nginx/authentik-location.conf;

        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app seerr;
        set $upstream_port 5055;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;

    }

    location ~ (/seerr)?/api {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app seerr;
        set $upstream_port 5055;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;

    }
}

Press :kbd{value="Ctrl+O"}, then :kbd{value="Enter"} to save, and :kbd{value="Ctrl+X"} to exit.

Wait a few minutes, then visit http://films.mydomain.com in your browser.

Done !

::

::caution

If it fails: check your firewall rules. ::

And there you go, Seerr is now publicly accessible!

Protecting Seerr with TinyAuth

Add TinyAuth's forward-auth check directly to films.subdomain.conf, the same way as the TinyAuth guide. The web UI (/) gets the check; /api is left out, since Seerr's own API calls (and anything integrating with it) can't do an interactive browser login:

## Version 2024/07/16
# make sure that your seerr container is named seerr
# make sure that your dns has a cname set for seerr

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name films.*;

    include /config/nginx/ssl.conf;

    client_max_body_size 0;

    # enable for ldap auth (requires ldap-location.conf in the location block)
    #include /config/nginx/ldap-server.conf;

    # enable for Authelia (requires authelia-location.conf in the location block)
    #include /config/nginx/authelia-server.conf;

    # enable for Authentik (requires authentik-location.conf in the location block)
    #include /config/nginx/authentik-server.conf;

    location /tinyauth {
        internal;
        proxy_pass http://tinyauth:3000/api/auth/nginx;
        proxy_pass_request_body off;
        proxy_set_header Content-Length "";
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $http_host;
        proxy_set_header X-Forwarded-Uri $request_uri;
    }

    location @tinyauth_login {
        return 302 https://tinyauth.mydomain.com/login?redirect_uri=$scheme://$http_host$request_uri;
    }

    location / {
        auth_request /tinyauth;
        error_page 401 = @tinyauth_login;

        # enable the next two lines for http auth
        #auth_basic "Restricted";
        #auth_basic_user_file /config/nginx/.htpasswd;

        # enable for ldap auth (requires ldap-server.conf in the server block)
        #include /config/nginx/ldap-location.conf;

        # enable for Authelia (requires authelia-server.conf in the server block)
        #include /config/nginx/authelia-location.conf;

        # enable for Authentik (requires authentik-server.conf in the server block)
        #include /config/nginx/authentik-location.conf;

        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app seerr;
        set $upstream_port 5055;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;

    }

    location ~ (/seerr)?/api {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app seerr;
        set $upstream_port 5055;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;

    }
}

::note

The location /tinyauth block runs inside SWAG's own container, so SWAG needs to be on TinyAuth's Docker network to reach it by name (tinyauth here). This should already be set up from exposing TinyAuth itself. If you run into an error, double-check SWAG's compose file still has that network attached. ::

::tip{icon=""} You can protect this app with Authentik instead of TinyAuth by opening films.subdomain.conf and removing the # in front of include /config/nginx/authentik-server.conf;{lang=nginx} and include /config/nginx/authentik-location.conf;{lang=nginx}. Don't forget to create an application and provider in Authentik. ::