Switch the media stack from Plex to Jellyfin and Overseerr to Seerr

This commit is contained in:
Djeex
2026-08-31 23:38:40 +02:00
parent 81df3351f5
commit 91ea3f9a70
7 changed files with 317 additions and 110 deletions
+7 -7
View File
@@ -46,7 +46,7 @@ Consider:
- Clock speed in GHz - Clock speed in GHz
- Power consumption in Watts - Power consumption in Watts
For low-power home servers or NAS (non-intensive computing), consider Intel N100/150 (4 cores) or N305/N355 (8 cores)efficient and low power (ideal for 24/7 uptime). For low-power home servers or NAS (non-intensive computing), consider Intel N100/150 (4 cores) or N305/N355 (8 cores), efficient and low power (ideal for 24/7 uptime).
## RAM ## RAM
@@ -60,9 +60,9 @@ Comes as sticks installed on the motherboard. Varies by format and generation (c
## GPU ## GPU
The __GPU__ (Graphics Processing Unit) handles graphical, video, and sometimes AI-related processing. Its main theoretical use is to display the image on your screen. In servers, it's useful for media centers (e.g. [Plex](/serveex/media/plex)) and for accelerating AI tasks like facial recognition or photo indexing (e.g. [Immich](/serveex/cloud/immich)). The __GPU__ (Graphics Processing Unit) handles graphical, video, and sometimes AI-related processing. Its main theoretical use is to display the image on your screen. In servers, it's useful for media centers (e.g. [Jellyfin](/serveex/media/jellyfin)) and for accelerating AI tasks like facial recognition or photo indexing (e.g. [Immich](/serveex/cloud/immich)).
Depending on the required performance, one can choose between a dedicated GPU with its own VRAM (a graphics card connected to a PCIe slot on the motherboard), or an iGPUan integrated GPU built into the CPU (such as the N100/N150 or N305/N355), which uses the systems shared RAM. Depending on the required performance, one can choose between a dedicated GPU with its own VRAM (a graphics card connected to a PCIe slot on the motherboard), or an iGPU, an integrated GPU built into the CPU (such as the N100/N150 or N305/N355), which uses the systems shared RAM.
### HDD(s) ### HDD(s)
@@ -70,7 +70,7 @@ Depending on the required performance, one can choose between a dedicated GPU wi
<img src="/img/global/hdd.svg" alt="Image" style="max-width: 50%; margin-right: 20px;"> <img src="/img/global/hdd.svg" alt="Image" style="max-width: 50%; margin-right: 20px;">
</p> </p>
An __HDD__ (Hard Disk Drive), or hard drive, is a component used to store data. It was once the standard storage device in computers. HDDs consist of one or more stacked platters and read/write headssomewhat like a vinyl record player. An __HDD__ (Hard Disk Drive), or hard drive, is a component used to store data. It was once the standard storage device in computers. HDDs consist of one or more stacked platters and read/write heads, somewhat like a vinyl record player.
Today, HDDs can store enormous amounts of data (up to 30TB, or 30,000 gigabytes, for consumer models), but their read and write speeds are limited due to their mechanical nature. They are also bulky and heavy. Today, HDDs can store enormous amounts of data (up to 30TB, or 30,000 gigabytes, for consumer models), but their read and write speeds are limited due to their mechanical nature. They are also bulky and heavy.
@@ -90,15 +90,15 @@ Comes in 3.5" and 2.5" formats; servers usually favor the more reliable 3.5".
An __SSD__ (Solid State Drive) is a small circuit board with memory chips soldered onto it, used to store information. Unlike RAM, these chips retain data even when not powered, meaning the information is preserved after a reboot. SSDs are generally used as the main storage medium for your server. An __SSD__ (Solid State Drive) is a small circuit board with memory chips soldered onto it, used to store information. Unlike RAM, these chips retain data even when not powered, meaning the information is preserved after a reboot. SSDs are generally used as the main storage medium for your server.
Unlike HDDs, SSDs have no moving parts, are highly compact, and most importantly, are extremely fastoffering speeds of several gigabytes per second for high-performance models. Unlike HDDs, SSDs have no moving parts, are highly compact, and most importantly, are extremely fast, offering speeds of several gigabytes per second for high-performance models.
SSDs come in various formats, but today the preferred choice is the M.2 NVMe version, as it is the smallest, fastest, and has become the standard on modern motherboards. SSDs come in various formats, but today the preferred choice is the M.2 NVMe version, as it is the smallest, fastest, and has become the standard on modern motherboards.
However, SSDs are significantly more expensive than hard drives for the same storage capacity. Typically, the operating system (OS) is installed on the SSD to ensure fast performance. In a server environment, it's also ideal to store [Docker containers](/serveex/core/docker) and databases on the SSD. More broadly, any data that needs to be accessed frequently and quicklysuch as websites, applications, or processing workloadsshould be stored on an SSD. However, SSDs are significantly more expensive than hard drives for the same storage capacity. Typically, the operating system (OS) is installed on the SSD to ensure fast performance. In a server environment, it's also ideal to store [Docker containers](/serveex/core/docker) and databases on the SSD. More broadly, any data that needs to be accessed frequently and quickly, such as websites, applications, or processing workloads, should be stored on an SSD.
### Network Card ### Network Card
A __network card__ allows your machine to communicate with your network (including the internet). It consists of a controller chip and one or more network ports. These portsoften Ethernet portscan come in different physical formats and support various data transfer standards: A __network card__ allows your machine to communicate with your network (including the internet). It consists of a controller chip and one or more network ports. These ports, often Ethernet ports, can come in different physical formats and support various data transfer standards:
- __RJ45 Gigabit Ethernet (10/100/1000):__ The standard RJ45 connector, supporting speeds from 10 Mbps (0.125 MB/s) up to 1000 Mbps (125 MB/s). - __RJ45 Gigabit Ethernet (10/100/1000):__ The standard RJ45 connector, supporting speeds from 10 Mbps (0.125 MB/s) up to 1000 Mbps (125 MB/s).
- __RJ45 2.5G:__ Same connector type, supporting up to 2.5 Gbps (2,500 Mbps or 312.5 MB/s). - __RJ45 2.5G:__ Same connector type, supporting up to 2.5 Gbps (2,500 Mbps or 312.5 MB/s).
@@ -8,7 +8,7 @@ description: Build a capable home server on a budget using an Intel N100 mini PC
::note ::note
This article was written before the __massive__ increase in computer hardware prices we've been experiencing since late 2025. However, setting costs aside, it remains just as relevant. This article was written before the __massive__ increase in computer hardware prices we've been experiencing since late 2025. However, setting costs aside, it remains just as relevant.
:: ::
When you decide to dive into the adventure of running your own home server, the same questions usually come up: _“Where should I start?”_, _“Isnt it expensive?”_. And often, people either give up or end up buying a proprietary NAS that theyll throw away a year later once they realize it only brings headaches and wasted money. When you decide to dive into the adventure of running your own home server, the same questions usually come up: _“Where should I start?”_, _“Isnt it expensive?”_. And often, people either give up or end up buying a proprietary NAS that theyll throw away a year later once they realize it only brings headaches and wasted money.
@@ -24,15 +24,15 @@ Thats all a **ProloNAS** is. Its then up to you to scale your storage capa
## Example Hardware ## Example Hardware
- Mini PC **Note: choose 16 GB / 512 GB**: [Aliexpress](https://fr.aliexpress.com/item/1005008477986765.html) - Mini PC (**Note: choose 16 GB / 512 GB**): [Aliexpress](https://fr.aliexpress.com/item/1005008477986765.html)
- DAS (Direct Attached Storage) **Note: select “EU plug”**: [Aliexpress](https://fr.aliexpress.com/item/1005007933987260.html) - DAS (Direct Attached Storage) (**Note: select “EU plug”**): [Aliexpress](https://fr.aliexpress.com/item/1005007933987260.html)
- More refined alternative with a fan: [Amazon](https://www.amazon.fr/Boîtier-Disque-Ventilateur-Supportant-Capacité/dp/B0DD3GSSCX) - More refined alternative with a fan: [Amazon](https://www.amazon.fr/Boîtier-Disque-Ventilateur-Supportant-Capacité/dp/B0DD3GSSCX)
> *These are not affiliate links buy wherever you prefer.* > *These are not affiliate links, buy wherever you prefer.*
## Why a NAS? ## Why a NAS?
A **NAS** (Network Attached Storage) is a machine centered around storage, designed to be shared over a network.The idea is to have a **reliable and secure** storage space that serves as the backbone for your personal services and apps such as a self-hosted cloud like [Nextcloud](/serveex/cloud/nextcloud), a photo sync tool like [Immich](/serveex/cloud/immich), or a media server like [Plex](/serveex/media/plex). You can also store camera footage, backups, or even development projects on it. A **NAS** (Network Attached Storage) is a machine centered around storage, designed to be shared over a network.The idea is to have a **reliable and secure** storage space that serves as the backbone for your personal services and apps such as a self-hosted cloud like [Nextcloud](/serveex/cloud/nextcloud), a photo sync tool like [Immich](/serveex/cloud/immich), or a media server like [Jellyfin](/serveex/media/jellyfin). You can also store camera footage, backups, or even development projects on it.
### But why not just use a mini PC with an external hard drive? ### But why not just use a mini PC with an external hard drive?
+3 -3
View File
@@ -66,7 +66,7 @@ Expose your services with SWAG
::card-group ::card-group
::card{icon="i-noto-key" title="SSO & MFA" to="/serveex/security/authentik"} ::card{icon="i-noto-key" title="SSO & MFA" to="/serveex/advanced/authentik"}
Install and deploy Authentik Install and deploy Authentik
:: ::
@@ -110,8 +110,8 @@ Install and deploy UpSnap
::: :::
::card-group ::card-group
::card{icon="i-cbi-plex-alt" title="Media" to="/serveex/media/plex"} ::card{icon="i-simple-icons-jellyfin" title="Media" to="/serveex/media/jellyfin"}
Install and deploy Plex Install and deploy Jellyfin
:: ::
::card{icon="i-cbi-qbittorrent" title="Seedbox" to="/serveex/media/qbittorrent"} ::card{icon="i-cbi-qbittorrent" title="Seedbox" to="/serveex/media/qbittorrent"}
@@ -1,6 +1,6 @@
--- ---
title: Cloudflare Zero Trust title: Cloudflare Zero Trust
description: Use Cloudflare Tunnels and Zero Trust to expose homelab services without opening ports configure SWAG and manage multiple tunnels. description: Use Cloudflare Tunnels and Zero Trust to expose homelab services without opening ports, configure SWAG and manage multiple tunnels.
--- ---
@@ -21,7 +21,7 @@ description: Use Cloudflare Tunnels and Zero Trust to expose homelab services wi
## Introduction ## Introduction
The _Zero Trust_ architecture is the practice of designing systems based on the principle of __"never trust, always verify"__, as opposed to the traditional principle of __"trust, but verify"__. This concept has become increasingly popular recently due to the growing number of attacks targeting user data. Its a broad concept, but well focus on how to apply _Zero Trust_ to the web services we host. The _Zero Trust_ architecture is the practice of designing systems based on the principle of __"never trust, always verify"__, as opposed to the traditional principle of __"trust, but verify"__. This concept has become increasingly popular recently due to the growing number of attacks targeting user data. Its a broad concept, but well focus on how to apply _Zero Trust_ to the web services we host.
_Cloudflare tunnels_ offer a simple way to implement _Zero Trust_, using [SWAG](/serveex/core/swag) and [Authentik](/serveex/security/authentik). _Cloudflare tunnels_ offer a simple way to implement _Zero Trust_, using [SWAG](/serveex/core/swag) and [Authentik](/serveex/advanced/authentik).
Simply put, Cloudflare Tunnels allow you to: Simply put, Cloudflare Tunnels allow you to:
@@ -37,7 +37,7 @@ Here well explain how to integrate SWAG with Cloudflare tunnels.
- __Warning:__ - __Warning:__
- Do not use Cloudflare tunnels to expose a mail server - Do not use Cloudflare tunnels to expose a mail server
- Do not use Cloudflare tunnels to expose a video service like Plex (if you followed [this guide](/serveex/media/plex), Plex is not exposed, so its fine) - Do not use Cloudflare tunnels to expose a video service like Jellyfin. Unlike Plex, [Jellyfin has no cloud relay](/serveex/media/jellyfin) and is exposed directly through SWAG in this guide, so make sure it stays behind plain port forwarding rather than a Cloudflare tunnel
- Do not use Cloudflare tunnels for the BitTorrent protocol (if you followed [this guide](/serveex/media/qbittorrent), everything is fine) - Do not use Cloudflare tunnels for the BitTorrent protocol (if you followed [this guide](/serveex/media/qbittorrent), everything is fine)
:: ::
@@ -68,7 +68,7 @@ Once created, your token will only be shown once. Save it securely, as it cannot
### Cloudflare Zero Trust ### Cloudflare Zero Trust
You must register for _Cloudflare Teams_ to access the _Zero Trust_ dashboard that manages tunnels and access policies. This is a premium service, but theres a free plan for up to 50 usersperfect for a home lab. Keep in mind that a valid credit card is required to register, but the free plan incurs no charges. You must register for _Cloudflare Teams_ to access the _Zero Trust_ dashboard that manages tunnels and access policies. This is a premium service, but theres a free plan for up to 50 users, perfect for a home lab. Keep in mind that a valid credit card is required to register, but the free plan incurs no charges.
Register [via this link](https://dash.teams.cloudflare.com/). Register [via this link](https://dash.teams.cloudflare.com/).
@@ -218,12 +218,12 @@ TUNNEL_PW=
| `TUNNEL_NAME` | Tunnel name | `my_tunnel` | | `TUNNEL_NAME` | Tunnel name | `my_tunnel` |
| `TUNNEL_PW` | Strong, random password | `iSzKRmP4VbnlsMvdSdgBEJiJi` | | `TUNNEL_PW` | Strong, random password | `iSzKRmP4VbnlsMvdSdgBEJiJi` |
Once done, deploy the stack. Check the logsyou should reach `server ready`. Once done, deploy the stack. Check the logs: you should reach `server ready`.
Then confirm your tunnel appears under _Networks > Tunnels_ in [Cloudflare Zero Trust](https://one.dash.cloudflare.com/). By default, all subdomains will be routed through the tunnelno need to define them [in your DNS zone](/general/networking/dns). Then confirm your tunnel appears under _Networks > Tunnels_ in [Cloudflare Zero Trust](https://one.dash.cloudflare.com/). By default, all subdomains will be routed through the tunnel, no need to define them [in your DNS zone](/general/networking/dns).
::tip{icon=""} ::tip{icon=""}
✨ __Tip:__ If you want to expose a service without a tunnel, just define an A record [in your DNS zone](/general/networking/dns). If resolution fails, disable the proxy function for that recorde.g., for `sub.mondomaine.fr`. ✨ __Tip:__ If you want to expose a service without a tunnel, just define an A record [in your DNS zone](/general/networking/dns). If resolution fails, disable the proxy function for that record, e.g. for `sub.mondomaine.fr`.
![dns](/img/serveex/cf-dns.png) ![dns](/img/serveex/cf-dns.png)
:: ::
+227
View File
@@ -0,0 +1,227 @@
---
title: Jellyfin
description: Install Jellyfin, a free and open-source media server, to stream your movies and TV shows from anywhere without a paid subscription.
---
:ellipsis{left=0px width=40rem top=10rem blur=140px zIndex=60}
# Jellyfin
::note
🎯 __Objectives:__
- Install Jellyfin
- Access your media from outside your network
::
[Jellyfin](https://jellyfin.org) is a free, open-source alternative to Plex and Emby. Unlike Plex, it has no paid tiers, no telemetry, and doesn't require an online account to use or manage your server: everything runs locally and stays yours.
It covers the same basics: a media library with metadata and artwork, transcoding (including hardware acceleration), and apps for TV, Android, iOS, Windows, and macOS.
As always, we'll use the [linuxserver.io image](https://docs.linuxserver.io/images/docker-jellyfin).
::note
Unlike Plex, Jellyfin has no cloud relay: to access your server outside your local network, you must expose it yourself (see below), or use a VPN like [Wireguard](/serveex/security/wireguard).
::
## Install Jellyfin
Folder structure:
```text [Directory tree]
root
├── docker
│ └── jellyfin
│ ├── compose.yaml
│ ├── .env
│ └── config
└── media
├── tvseries
├── movies
└── library
```
Create the `movies`, `tvseries`, and `library` folders in `/media`:
```bash [Terminal]
mkdir -p /media/movies /media/library /media/tvseries
```
Open Dockge, click `compose`, name the stack `jellyfin`, and add the following config:
```yaml [compose.yaml]
---
services:
jellyfin:
image: lscr.io/linuxserver/jellyfin:latest
container_name: jellyfin
environment:
- PUID=${PUID}
- PGID=${GUID}
- TZ=Europe/Paris
volumes:
- /docker/jellyfin/config:/config
- /media:/media
restart: unless-stopped
devices:
- /dev/dri:/dev/dri
ports:
- 8096:8096
```
::tip
✨ Add the Watchtower label to automate updates:
```yaml [compose.yaml]
services:
jellyfin:
#...
labels:
- com.centurylinklabs.watchtower.enable=true
```
::
Find your PUID and GUID by running:
```bash [Terminal]
id username
```
Fill in your `.env` file with the retrieved values, for example:
```properties [.env]
PUID=1000
GUID=1000
```
Deploy the stack. The local interface is available at `http://yourserverip:8096`.
::note
The `/dev/dri` device is only needed for hardware-accelerated transcoding on Intel/AMD GPUs. Remove it if your server doesn't have one, or adapt it for an NVIDIA GPU following [linuxserver.io's documentation](https://docs.linuxserver.io/images/docker-jellyfin/#hardware-acceleration).
::
## Configure Jellyfin
On first visit, Jellyfin walks you through a setup wizard:
- Choose a display language and create your admin account.
- Add a media library, pointing to `/media/movies` for movies and `/media/tvseries` for TV shows.
- (Optional) Enable hardware acceleration in _Dashboard > Playback_ if you have a compatible GPU.
And that's it! Add your media to `/media/movies` and `/media/tvseries` on your server, then install the Jellyfin app on your devices to watch locally or remotely.
::note
If your media is stored on a network disk (e.g. NAS or external hard drive over the network), refer to the [Samba mount guide](/general/networking/samba) so Jellyfin can access it.
::
## Expose Jellyfin with Swag
To access Jellyfin outside your local network, we'll expose it through Swag.
::note
We assume you have the subdomain `jellyfin.mydomain.com` with a `CNAME` pointing to `mydomain.com` in your [DNS zone](/general/networking/dns). And of course, [unless you use Cloudflare Zero Trust](/serveex/security/cloudflare), your box's port `443` must be forwarded to your server's port `443` in [NAT rules](/general/networking/nat).
::
Go to Dockge and edit SWAG's compose file by adding Jellyfin's network:
```yaml [compose.yaml]
services:
swag:
container_name: # ...
# ...
networks: # Attach container to custom network
# ...
- jellyfin # Name of the declared network
networks: # Define the custom network
# ...
jellyfin: # Declared network name
name: jellyfin_default # Actual external network name
external: true # Marks it as externally defined
```
Redeploy the stack and wait for SWAG to be fully operational.
::note
Here we assume the Jellyfin network name is `jellyfin_default`. You can check the connection by visiting SWAG's dashboard at `http://yourserverip:81`.
::
In the Swag folders, create the file `jellyfin.subdomain.conf`:
::tip{icon=""}
✨ __Tip:__ Use [File Browser](/serveex/files/file-browser) to navigate and edit files instead of using terminal commands.
::
```bash [Terminal]
sudo nano /docker/swag/config/nginx/proxy-confs/jellyfin.subdomain.conf
```
Paste the following configuration:
```nginx [jellyfin.subdomain.conf]
## Version 2023/12/19
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name jellyfin.*;
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 jellyfin;
set $upstream_port 8096;
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 open `https://jellyfin.mydomain.com` in your browser.
::caution
__If it fails:__ check your firewall rules.
::
::tip{icon=""}
✨ __Tip:__ You can protect this app with [TinyAuth](/serveex/security/tinyauth) and [Pocket ID](/serveex/security/pocket-id) using the reverse-proxy pattern from the TinyAuth guide, or with Authentik by opening `jellyfin.subdomain.conf` and uncommenting `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](/serveex/advanced/authentik#protecting-an-app-via-reverse-proxy).
::
And you're done!
@@ -41,7 +41,7 @@ root
│ ├── compose.yaml │ ├── compose.yaml
│ └── .env │ └── .env
└── media #linked to Plex and Qbittorrent └── media #linked to Jellyfin and Qbittorrent
├── downloads #generic downloads, selected in settings ├── downloads #generic downloads, selected in settings
├── movies #used for downloading movies ├── movies #used for downloading movies
└── tvseries #used for downloading TV shows └── tvseries #used for downloading TV shows
@@ -209,13 +209,13 @@ Change your username and password in the "webui" settings.
You're done! In Qbittorrent settings, under "Downloads", set `/media/downloads` as the default folder. You're done! In Qbittorrent settings, under "Downloads", set `/media/downloads` as the default folder.
When adding a download, remember to select the proper directory so Plex can sync correctly (`/media/movies` or `/media/tvseries`). You can also automate this with categories and folders. When adding a download, remember to select the proper directory so Jellyfin can sync correctly (`/media/movies` or `/media/tvseries`). You can also automate this with categories and folders.
## Exposing the Web UI ## Exposing the Web UI
::warning ::warning
Qbittorrent does not support multi-factor authentication. Exposing it to the internet may put your system at risk. Only do this if you use MFA via [Authentik](/serveex/security/authentik/). Otherwise, dont expose it with SWAG—use a VPN like [Wireguard](/serveex/security/wireguard) instead. Qbittorrent does not support multi-factor authentication. Exposing it to the internet may put your system at risk. Only do this if you use MFA via [Authentik](/serveex/advanced/authentik/). Otherwise, dont expose it with SWAG. Use a VPN like [Wireguard](/serveex/security/wireguard) instead.
:: ::
To start downloads from outside your home, without a VPN, you can expose the Qbittorrent web UI. To start downloads from outside your home, without a VPN, you can expose the Qbittorrent web UI.
@@ -315,12 +315,12 @@ server {
``` ```
::tip ::tip
✨ You can secure this app with Authentik by uncommenting the `authentik-server.conf` and `authentik-location.conf` lines. Dont forget to [create an app and provider in Authentik](/serveex/security/authentik#protecting-an-app-via-reverse-proxy). ✨ You can secure this app with [TinyAuth](/serveex/security/tinyauth) and [Pocket ID](/serveex/security/pocket-id) using the reverse-proxy pattern from the TinyAuth guide, or with Authentik by uncommenting the `authentik-server.conf` and `authentik-location.conf` lines. Dont forget to [create an app and provider in Authentik](/serveex/advanced/authentik#protecting-an-app-via-reverse-proxy).
:: ::
Press :kbd{value="Ctrl+O"}, then :kbd{value="Enter"} to save, and :kbd{value="Ctrl+X"} to exit. Press :kbd{value="Ctrl+O"}, then :kbd{value="Enter"} to save, and :kbd{value="Ctrl+X"} to exit.
Wait a few minutes, then go to `https://seedbox.mydomain.com`—you should land on the Qbittorrent interface. Wait a few minutes, then go to `https://seedbox.mydomain.com`. You should land on the Qbittorrent interface.
And thats it! You now have a ready-to-use media center. And thats it! You now have a ready-to-use media center.
+63 -83
View File
@@ -1,6 +1,6 @@
--- ---
title: Automation title: Automation
description: Automate media downloads with the Servarr stack Radarr, Sonarr, Bazarr, Prowlarr, and Overseerr for movies and TV shows. description: Automate media downloads with the Servarr stack, Radarr, Sonarr, Bazarr, Prowlarr, and Seerr, for movies and TV shows.
--- ---
@@ -10,13 +10,13 @@ description: Automate media downloads with the Servarr stack — Radarr, Sonarr,
::note ::note
🎯 __Goals:__ 🎯 __Goals:__
Automate movie and TV show downloads using Radarr, Sonarr, Bazarr, Prowlarr, and Overseerr. Automate movie and TV show downloads using Radarr, Sonarr, Bazarr, Prowlarr, and Seerr.
:: ::
[Servarr](https://wiki.servarr.com/) 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: [Servarr](https://wiki.servarr.com/) 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. - Selecting a movie from a catalog through a web interface.
- Sitting back and enjoying it on Plex a few minutes later. - Sitting back and enjoying it on Jellyfin a few minutes later.
Simple. Simple.
@@ -33,11 +33,8 @@ Folder structure:
```text [Directory tree] ```text [Directory tree]
root root
├── docker ├── docker
│ ├── plex │ ├── jellyfin
│ │ ├── compose.yml │ │ ├── compose.yml
│ │ ├── config
│ │ └── transcode
│ ├── tautulli
│ │ └── config │ │ └── config
│ ├── sonarr │ ├── sonarr
│ │ └── config │ │ └── config
@@ -47,7 +44,7 @@ root
│ │ └── config │ │ └── config
│ ├── prowlarr │ ├── prowlarr
│ │ └── config │ │ └── config
│ └── overseerr │ └── seerr
│ └── config │ └── config
└── media └── media
├── downloads ├── downloads
@@ -60,53 +57,33 @@ root
__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. __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_. 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. Without hardlinks, the _arr_ apps will copy the files instead, **doubling the space used** on your storage.
:: ::
Open Docker and your `plex` stack. Modify the compose file as follows: Open Docker and your `jellyfin` stack. Modify the compose file as follows:
```yaml [compose.yaml] ```yaml [compose.yaml]
--- ---
services: services:
linuxserver_plex: jellyfin:
image: ghcr.io/linuxserver/plex:latest image: lscr.io/linuxserver/jellyfin:latest
container_name: plex container_name: jellyfin
network_mode: host
environment: environment:
- PUID=${PUID} - PUID=${PUID}
- PGID=${PGID} - PGID=${PGID}
- TZ=Europe/Paris - TZ=Europe/Paris
- VERSION=docker
- PLEX_CLAIM= #optional
volumes: volumes:
- /docker/plex/config:/config - /docker/jellyfin/config:/config
- /docker/plex/transcode:/transcode #optional
- ${MEDIA_PATH}:/media - ${MEDIA_PATH}:/media
labels:
- com.centurylinklabs.watchtower.enable=true
restart: unless-stopped restart: unless-stopped
mem_limit: 4096m
mem_reservation: 2048m
devices: devices:
- /dev/dri:/dev/dri - /dev/dri:/dev/dri
tautulli:
image: lscr.io/linuxserver/tautulli:latest
container_name: tautulli
environment:
- TZ=Europe/Paris
volumes:
- /docker/tautulli/config:/config
ports: ports:
- 8181:8181 - 8096:8096
restart: unless-stopped
sonarr: sonarr:
image: lscr.io/linuxserver/sonarr:latest image: lscr.io/linuxserver/sonarr:latest
container_name: sonarr container_name: sonarr
@@ -157,21 +134,16 @@ services:
- 9696:9696 - 9696:9696
restart: unless-stopped restart: unless-stopped
overseerr: seerr:
image: lscr.io/linuxserver/overseerr:latest image: ghcr.io/seerr-team/seerr:latest
container_name: overseerr container_name: seerr
dns:
- 1.1.1.1
- 8.8.8.8
environment: environment:
- PUID=${PUID} - LOG_LEVEL=info
- PGID=${PGID}
- TZ=Europe/Paris - TZ=Europe/Paris
volumes: volumes:
- /docker/overseerr/config:/config - /docker/seerr/config:/app/config
ports: ports:
- 5055:5055 - 5055:5055
@@ -200,13 +172,7 @@ services:
```yaml [compose.yaml] ```yaml [compose.yaml]
services: services:
plex: jellyfin:
#...
labels:
- com.centurylinklabs.watchtower.enable=true
tautulli:
#... #...
labels: labels:
@@ -228,6 +194,15 @@ MEDIA_PATH=
| `GUID` | Same as above | `1000` | | `GUID` | Same as above | `1000` |
| `MEDIA_PATH` | Path to your media folder, here: `/media`. It must match the one used by Qbittorrent. | `/media` | | `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:
```bash [Terminal]
sudo chown -R 1000:1000 /docker/seerr/config
```
::
Deploy the stack. Deploy the stack.
### Configure Radarr ### Configure Radarr
@@ -268,16 +243,18 @@ In *Settings > Download Clients*, add Qbittorrent.
- Click *Test*. - Click *Test*.
- If successful, click *Save*. - If successful, click *Save*.
##### Connect to Plex ##### Connect to Jellyfin
Go to *Settings > Connect*, add a new connection and choose *Plex Media Server*. First, get an API key from Jellyfin: log in as admin, go to *Dashboard > Advanced > API Keys*, and add a new one.
- Use `plex` or your server IP for *Host*. Then, in Radarr, go to *Settings > Connect*, add a new connection and choose *Jellyfin*.
- Port: `32400`
- Click the blue "authenticate with Plex.tv" button and log into Plex. - Use `jellyfin` or your server IP for *Host*.
- Port: `8096`
- Paste the API key you generated.
- Press *Test*, then *Save* if successful. - Press *Test*, then *Save* if successful.
##### Get API Key for Prowlarr and Overseerr ##### Get API Key for Prowlarr and Seerr
- Go to *Settings > General* and copy your *API Key* for later use. - Go to *Settings > General* and copy your *API Key* for later use.
@@ -358,13 +335,11 @@ Go to *Settings > General* and create a username and password using *forms login
Repeat the same steps for Radarr. Repeat the same steps for Radarr.
### Configuring Overseerr ### Configuring Seerr
[Overseerr](https://overseerr.dev/) 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 Plex without any manual intervention. [Seerr](https://seerr.dev/) (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.
![Overseerr](/img/serveex/overseerr.webp) Go to `http://yourserverip:5055`, select *Jellyfin* as your media server, and sign in with your Jellyfin admin account.
Go to `http://yourserverip:5055` and log in with your Plex account.
::caution ::caution
@@ -385,7 +360,7 @@ When prompted, add a Radarr server:
If the test succeeds, continue filling in the fields: If the test succeeds, continue filling in the fields:
- __Quality Profile:__ the one you configured (e.g., `any`) - __Quality Profile:__ the one you configured (e.g., `any`)
- __Root Folder:__ the Plex folder. In our examples: `/media/movies` - __Root Folder:__ the Jellyfin folder. In our examples: `/media/movies`
- __Minimum Availability:__ `Announced`. This allows requesting unreleased content and downloads it upon release. - __Minimum Availability:__ `Announced`. This allows requesting unreleased content and downloads it upon release.
- Check all 3 boxes at the bottom. - Check all 3 boxes at the bottom.
- Save and continue. - Save and continue.
@@ -402,46 +377,51 @@ Now do the same for Sonarr:
If the test succeeds, continue filling in the fields: If the test succeeds, continue filling in the fields:
- __Quality Profile:__ the one you configured (e.g., `any`) - __Quality Profile:__ the one you configured (e.g., `any`)
- __Root Folder:__ the Plex folder. In our examples: `/media/tvseries` - __Root Folder:__ the Jellyfin folder. In our examples: `/media/tvseries`
- __Language Profile:__ `Deprecated` - __Language Profile:__ `Deprecated`
- Check all 4 boxes at the bottom. - Check all 4 boxes at the bottom.
- Save and continue. - Save and continue.
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 Plex! 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 Overseerr with SWAG ## Exposing Seerr with SWAG
It can be useful to expose Overseerr if you want to send requests from outside your network without a VPN, or if you've shared your Plex library with others and want them to have Overseerr access. 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](/serveex/security/tinyauth) with [Pocket ID](/serveex/security/pocket-id), or [Authentik](/serveex/advanced/authentik). Otherwise, don't expose it with SWAG, use a VPN like [Wireguard](/serveex/security/wireguard) instead.
::
::note ::note
We assume you have the subdomain `films.mydomain.com` with a `CNAME` pointing to `films.fr` in your [DNS zone](/general/networking/dns). And that [unless youre using Cloudflare Zero Trust](/serveex/security/cloudflare), port `443` on your router is forwarded to port `443` on your server via [NAT rules](/general/networking/nat). We assume you have the subdomain `films.mydomain.com` with a `CNAME` pointing to `films.fr` in your [DNS zone](/general/networking/dns). And that [unless youre using Cloudflare Zero Trust](/serveex/security/cloudflare), port `443` on your router is forwarded to port `443` on your server via [NAT rules](/general/networking/nat).
:: ::
Go to Dockge, edit the SWAG compose file, and add the Overseerr network, which is the same as Plex (since its in the Plex stack): 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):
```yaml [compose.yaml] ```yaml [compose.yaml]
services: services:
swag: swag:
container_name: # ... container_name: # ...
# ... # ...
networks: # Connects the container to a custom network networks: # Connects the container to a custom network
# ... # ...
- plex # Name of the network declared in the stack - jellyfin # Name of the network declared in the stack
networks: # Defines the custom network networks: # Defines the custom network
# ... # ...
plex: # Name of the declared network jellyfin: # Name of the declared network
name: plex_default # Actual name of the external network name: jellyfin_default # Actual name of the external network
external: true # Indicates its an external network external: true # Indicates its an external network
``` ```
Restart the stack by clicking “Deploy” and wait until SWAG is fully operational. Restart the stack by clicking “Deploy” and wait until SWAG is fully operational.
::note ::note
Here we assume the Tautulli network is named `plex_default`. You can verify the connection works by visiting the SWAG dashboard at `http://yourserverip:81`. 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 and edit the file `films.subdomain.conf`: Create and edit the file `films.subdomain.conf`:
@@ -458,8 +438,8 @@ Paste the following:
```nginx [films.subdomain.conf] ```nginx [films.subdomain.conf]
## Version 2024/07/16 ## Version 2024/07/16
# make sure that your overseerr container is named overseerr # make sure that your seerr container is named seerr
# make sure that your dns has a cname set for overseerr # make sure that your dns has a cname set for seerr
server { server {
listen 443 ssl; listen 443 ssl;
@@ -496,17 +476,17 @@ server {
include /config/nginx/proxy.conf; include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf; include /config/nginx/resolver.conf;
set $upstream_app overseerr; set $upstream_app seerr;
set $upstream_port 5055; set $upstream_port 5055;
set $upstream_proto http; set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port; proxy_pass $upstream_proto://$upstream_app:$upstream_port;
} }
location ~ (/overseerr)?/api { location ~ (/seerr)?/api {
include /config/nginx/proxy.conf; include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf; include /config/nginx/resolver.conf;
set $upstream_app overseerr; set $upstream_app seerr;
set $upstream_port 5055; set $upstream_port 5055;
set $upstream_proto http; set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port; proxy_pass $upstream_proto://$upstream_app:$upstream_port;
@@ -524,4 +504,4 @@ Wait a few minutes, then visit `http://films.mydomain.com` in your browser.
__If it fails:__ check your firewall rules. __If it fails:__ check your firewall rules.
:: ::
And there you go, Overseerr is now publicly accessible! And there you go, Seerr is now publicly accessible!