(I’m planning on rewriting this with more detailed sections later)
Hi!! This post is suppose to be more like a “dump” about the whole process rather than educational, so I’m sorry for the lack of the explanations :D
This content will contain a lot of text pasted from other guides like:
- Trash’s guides
- I thought there were more but I forgot, you will probably find the links through the post :D
The setup will use.
- Plex Media Server and Plex Streaming, it’s where you’re gonna watch your media.
- Radarr to manage movies
- Sonarr to manage series and animes.
- QbitTorrent as download client.
- Prowlarr for indexers, that’s where the downloads come from.
- FlareSolver for Prowlarr, plugin to make you have access to more trackers.
- Zero Tier for VPN, to access your library even when you’re not home.
- Overseer, centralized app to search the content.
Choosing where to store data
Consistent and well planned paths to avoid copying data and wasting space:
The easiest and most important detail is to create unified path definitions across all the containers.
If you’re wondering why hard links aren’t working or why a simple move is taking far longer than it should, this section explains it. The paths you use on the inside matter. Because of how Docker’s volumes work, passing in two volumes such as the commonly suggested /tv, /movies, and /downloads makes them look like two different file systems, even if they are a single file system outside the container. This means hard links won’t work and instead of an instant/atomic move, a slower and more IO intensive copy+delete is used. If you have multiple download clients because you’re using torrents and usenet, having a single /downloads path means they’ll be mixed up. Because the Radarr in one container will ask the NZBGet in its own container where files are, using the same path in both means it will all just work. If you don’t, you’d need to fix it with a remote path map.
So pick one path layout and use it for all of them. It’s suggested to use /data, but there are other common names like /shared, /media or /dvr. Keeping this the same on the outside and inside will make your setup simpler: one path to remember or if integrating Docker and native software. For example, Synology might use /Volume1/data and unRAID might use /mnt/user/data on the outside, but /data on the inside is fine.
It is also important to remember that you’ll need to setup or re-configure paths in the software running inside these Docker containers. If you change the paths for your download client, you’ll need to edit its settings to match and likely update existing torrents. If you change your library path, you’ll need to change those settings in Sonarr, Radarr, Lidarr, Plex, etc.
Examples What matters here is the general structure, not the names. You are free to pick folder names that make sense to you. And there are other ways of arranging things too. For example, you’re not likely to download and run into conflicts of identical releases between usenet and torrents, so you could put both in /data/downloads/{movies|books|music|tv} folders. Downloads don’t even have to be sorted into subfolders either, since movies, music and tv will rarely conflict.
This example data folder has subfolders for torrents and usenet and each of these have subfolders for tv, movie and music downloads to keep things neat. The media folder has nicely named tv, movies, books, and music subfolders. This media folder is your library and what you’d pass to Plex, Kodi, Emby, Jellyfin, etc.
Obs: Hardlinks are only deleted when all the inodes are deleted.
The setup will be:
data
├── torrents
│ ├── movies
│ ├── music
| ├── books
│ └── tv
├── usenet # optional
│ ├── movies
│ ├── music
│ ├── books
│ └── tv
└── media
├── movies
├── music
├── books
└── tv
qBittorrent - Download client
data
└── torrents
├── movies
├── music
├── books
└── tv
Torrents only needs access to torrent files, so pass it -v /host/data/torrents:/data/torrents. In the torrent software settings, you’ll need to reconfigure paths and you can sort into subfolders like/data/torrents/{tv|books|movies|music}.
docker run -d \
--name=qbittorrent \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=America/Sao_Paulo \
-e WEBUI_PORT=8080 \
-e TORRENTING_PORT=6881 \
-p 8080:8080 \
-p 6881:6881 \
-p 6881:6881/udp \
-v /home/akame/qbit/config:/config \
-v /home/akame/data/torrents:/data/torrents \
--restart=unless-stopped \
lscr.io/linuxserver/qbittorrent:latest
Get the password using:
docker ps -get container_id
docker logs container_id
You can do some configuration following: qBittorrent trash-guides but the important change here is to change the path to files downloads to /data/torrents:

Put a seed limit of 1.0 (I dont have much space to keep the file forever) Also enable subfolders to make radarr find the movies easier.

Radarr - Movie Organizer
data
├── torrents
│ ├── movies
│ ├── music
│ └── tv
├── usenet
│ ├── movies
│ ├── music
│ └── tv
└── media
├── movies
├── music
└── tv
Sonarr, Radarr and Lidarr get everything using -v /host/data:/data because the download folder(s) and media folder will look like and be one file system. Hard links will work and moves will be atomic, instead of copy + delete. The configuration of all of them should be similar, i will not post about them here if there is no specific change.
docker run -d \
--name=radarr \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=America/Sao_Paulo \
-p 7878:7878 \
-v /home/akame/radarr/config:/config \
-v /home/akame/data/:/data \
--restart unless-stopped \
lscr.io/linuxserver/radarr:latest
docker run -d \
--name=sonarr \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=America/Sao_Paulo \
-p 8989:8989 \
-v /home/akame/sonarr/config:/config \
-v /home/akame/data/:/data \
--restart unless-stopped \
lscr.io/linuxserver/sonarr:latest
Useful wiki if something here is missing: Wiki about Sonarr, Radarr and more
Go to http://server_ip:7878/ and change the following settings:
- Settings > Media Management > Root Folders - Add /data/media/movies (Raddar will only manage movies)
- Settings > Media Management > Movie Naming > Enable/Disable Renaming of your movies (as opposed to leaving the names that are currently there or as they were when you downloaded them).
- Enable Unmonitor Deleted Movies.
- WARN: Make sure HardLinks are enabled.
- Enable Import Extra Files and add srt.
Adding the qBittorent client:
WARN: Since Radarr will only manage movies, category here needs to be “movies”, it will created a folder under /data/torrents called “movies” or whatever name you put there to download the .mkv ’s there.

Add your client and in manage clients set Removed Completed to Yes:

Recyclarr - Syncing configs
# Download docker.
# Running: sudo docker exec recyclarr recyclarr sync --preview
services:
recyclarr:
image: ghcr.io/recyclarr/recyclarr
container_name: recyclarr
user: 1000:1000
volumes:
- /home/akame/recyclarr/config:/config
environment:
- TZ=America/Sao_Paulo
Paste the following config at: /home/akame/recyclarr/config/recyclarr.yml. It will create three profiles from Trash Custom Profiles:
- Sonarr -> WEB-1080p / WEB-2160p / Anime - 1080p Remux
- Radarr -> HD WEB + Bluray / FHD WEB + Bluray
# This file will create two quality profiles in radarr and sonarr, one for 4K and another for 1080p. They contain useful filters to get better torrents from prowlarr indexers. All the values and ids comes from the TrashGuides and are sync automatically.
# This file will also create a profile for Animes in Sonarr.
radarr:
radarr_merged:
base_url: http://192.168.1.100:7878/
api_key: <key>
include:
- template: radarr-quality-definition-movie
# HD Bluray + Web
- template: radarr-quality-profile-hd-bluray-web
- template: radarr-custom-formats-hd-bluray-web
# UHD Bluray + Web
- template: radarr-quality-profile-uhd-bluray-web
- template: radarr-custom-formats-uhd-bluray-web
quality_profiles:
- name: UHD Bluray + WEB
reset_unmatched_scores:
enabled: true
upgrade:
allowed: true
until_quality: Bluray-2160p
until_score: 10000
min_format_score: 0
quality_sort: top
qualities:
- name: Bluray-2160p
- name: WEB 2160p
qualities:
- WEBDL-2160p
- WEBRip-2160p
- name: Bluray-1080p
- name: WEB 1080p
qualities:
- WEBDL-1080p
- WEBRip-1080p
- name: Bluray-720p
custom_formats:
# Movie Versions
- trash_ids:
# Uncomment any of the following lines to prefer these movie versions
- 570bc9ebecd92723d2d21500f4be314c # Remaster
- eecf3a857724171f968a66cb5719e152 # IMAX
- 9f6cbff8cfe4ebbc1bde14c7b7bec0de # IMAX Enhanced
assign_scores_to:
- name: HD Bluray + WEB
- name: UHD Bluray + WEB
# Must have to avoid shit releases
- trash_ids:
- cc444569854e9de0b084ab2b8b1532b2 # Black and White Editions
assign_scores_to:
- name: HD Bluray + WEB
- name: UHD Bluray + WEB
- trash_ids:
# https://trash-guides.info/Radarr/radarr-setup-quality-profiles-anime/
# Avoid these formats:
- ed38b889b31be83fda192888e2286d83 # BR-DISK
- e6886871085226c3da1830830146846c # Generate Dynamic HDR
- 90a6f9a284dff5103f6346090e6280c8 # LQ
- e204b80c87be9497a8a6eaff48f72905 # LQ (Release Title)
- dc98083864ea246d05a42df0d05f81cc # x265 (HD)
- b8cd450cbfa689c0259a01d9e29ba3d6 # 3D
- 0a3f082873eb454bde444150b70253cc # Extras
- 712d74cd88bceb883ee32f773656b1f5 # Sing-Along Versions
- cae4ca30163749b891686f95532519bd # AV1
assign_scores_to:
- name: HD Bluray + WEB
- name: UHD Bluray + WEB
sonarr:
sonarr_merged:
base_url: http://192.168.1.100:8989/ # Update this with your Sonarr URL
api_key: <api_key> # Replace with your actual Sonarr API key
include:
# Common quality definitions
- template: sonarr-quality-definition-series
- template: sonarr-quality-definition-anime
# Quality profiles
- template: sonarr-v4-quality-profile-anime
- template: sonarr-v4-quality-profile-web-2160p
- template: sonarr-v4-quality-profile-web-1080p
# Custom formats with scores
- template: sonarr-v4-custom-formats-anime
- template: sonarr-v4-custom-formats-web-1080p
- template: sonarr-v4-custom-formats-web-2160p
# - template: sonarr-v4-quality-profile-web-2160p-alternative
# - template: sonarr-v4-quality-profile-web-1080p-alternative
# UHD Web + Bluray Configuration
quality_profiles:
- name: WEB-2160p # This name come from sonarr-v4-custom-formats-web-1080p
reset_unmatched_scores:
enabled: true
upgrade:
allowed: true
until_quality: Bluray-2160p
until_score: 10000
min_format_score: 0
quality_sort: top
qualities:
- name: Bluray-2160p
- name: WEB 2160p
qualities:
- WEBDL-2160p
- WEBRip-2160p
- name: Bluray-1080p
- name: WEB 1080p
qualities:
- WEBDL-1080p
- WEBRip-1080p
- name: Bluray-720p
- name: WEB 720p
qualities:
- WEBDL-720p
- WEBRip-720p
- name: HDTV-1080p
- name: HDTV-720p
# HD Web + Bluray Configuration
- name: WEB-1080p
reset_unmatched_scores:
enabled: true
upgrade:
allowed: true
until_quality: Bluray-1080p
until_score: 10000
min_format_score: 0
quality_sort: top
qualities:
- name: Bluray-1080p
- name: WEB 1080p
qualities:
- WEBDL-1080p
- WEBRip-1080p
- name: Bluray-720p
- name: WEB 720p
qualities:
- WEBDL-720p
- WEBRip-720p
- name: HDTV-1080p
- name: HDTV-720p
- name: Remux-1080p - Anime
reset_unmatched_scores:
enabled: true
upgrade:
allowed: true
until_quality: Bluray-1080p
until_score: 10000
min_format_score: 100
score_set: anime-sonarr
quality_sort: top
qualities:
- name: Bluray-1080p
qualities:
- Bluray-1080p Remux
- Bluray-1080p
- name: WEB 1080p
qualities:
- WEBDL-1080p
- WEBRip-1080p
- HDTV-1080p
- name: Bluray-720p
- name: WEB 720p
qualities:
- WEBDL-720p
- WEBRip-720p
- HDTV-720p
- name: Bluray-480p
- name: WEB 480p
qualities:
- WEBDL-480p
- WEBRip-480p
- name: DVD
- name: SDTV
custom_formats:
- trash_ids:
# - 497c863b88e147fda2807eb8197c41b8 # TrueHD ATMOS
# - a570d4a0e56a2874b64e5bfa55202a1b # FLAC
# - 2f22d89048b01681dde8afe203bf2e95 # DTS X
# - 3cafb66171b47f226146a0770576870f # TrueHD
# - dcf3ec6938fa32445f590a4da84256cd # DTS-HD MA
# - 8e109e50c0b8a8f3ef3d72a8859a8f27 # DTS-ES
# - d2516a5d9a83c99d16db8305c896408f # DTS
# - 417804f7f2c4308c1f4c5d380d4c4475 # ATMOS (undefined)
# - 1af239278386be2919e1bcee0bde047e # DD+ ATMOS
# - e7c2fcae07cbada050a0af3357491d7b # PCM
# - 3131e15a62c54d35c19f2a4e596cd5b5 # DD+
# - b9f8e3251d08204868ccd5d9d4c4ab71 # Dolby Digital Plus
# - 6ba9033d67b68ca3ef533d68f1ae93b5 # Dolby Digital
# - 9cf44037df3289f9a47defcb2d13e2d7 # AAC LC
assign_scores_to:
- name: WEB-1080p
- name: WEB-2160p
- trash_ids:
# https://trash-guides.info/Sonarr/sonarr-setup-quality-profiles/#trash-quality-profiles
# Avoid these formats:
- 85c61753df5da1fb2aab6f2a47426b09 # BR-DISK
- 9c11cd3f07101cdba90a2d81cf0e56b4 # LQ
- e2315f990da2e2cbfc9fa5b7a6fcfe48 # LQ (Release Title)
- 47435ece6b99a0b477caf360e79ba0bb # x265 (HD)
- fbcb31d8dabd2a319072b84fc0b7249c # Extras
- 15a05bc7c1a36e2b57fd628f8977e2fc # AV1
assign_scores_to:
- name: WEB-1080p
- name: WEB-2160p
Then use:
# Pray to have no errors, because merging configs looked like hell.
# Remember to also add language custom filters for the portuguese profiles directly in the UI
docker compose run --rm recyclarr sync
Prowlarr - Indexers
This one is so easy, go the Prowlarr webpage and add your qbittorrent and your *rrs apps and you are done. The indexers added by prowlarr will be in sync in all apps.
docker run -d \
--name=prowlarr \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=America/Sao_Paulo \
-p 9696:9696 \
-v /home/akame/prowlarr/config:/config \
--restart unless-stopped \
lscr.io/linuxserver/prowlarr:latest
# FlareSolver
docker run -d \
--name=flaresolverr \
-p 8191:8191 \
-e LOG_LEVEL=info \
--restart unless-stopped \
ghcr.io/flaresolverr/flaresolverr:latest
Installing Jackett instead of Prowlarr
Just use prowlarr, trust me.
WARN: It's better to use prowlarr to keep all *rrs* apps in sync
docker run -d \
--name=jackett \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=America/Sao_Paulo \
-e AUTO_UPDATE=true \
-p 9117:9117 \
-v /home/akame/jackett/config/:/config \
-v /home/akame/data/torrents:/data/torrents \
--restart unless-stopped \
lscr.io/linuxserver/jackett:latest
# Also run Flaresolver.
docker run -d \
--name=flaresolverr \
-p 8191:8191 \
-e LOG_LEVEL=info \
--restart unless-stopped \
ghcr.io/flaresolverr/flaresolverr:latest
Go to http://server_ip:9117 to add the trackers you want to search for stuff. At the bottom, in FlareSolver API url, add http://192.168.1.100:8191/
Go back to Radarr, we are going to add the indexes there:
Go to: Settings > Indexers > Add Indexer > Tornzab > Grab the link using “Copy Tornzab” in Jackett dashboard and the API KEY > Copy both in form for new indexer > Change Categories (Radarr will only take care of Movies, so let only Movies) > Change it’s name to match the indexer (optional)

Plex Media Server
Media Server
data
└── media
├── movies
├── music
└── tv
Plex only needs access to your media library, so pass -v /host/data/media:/data/media, which can have any number of sub folders like movies, kids movies, tv, documentary tv and/or music as sub folders.
Get docker file in this link plexinc docker
docker run \
-d \
--name plex \
--network=host \
-e PUId=$(id -u) -e PGID=$(id -g) \
-e VERSION=docker \
-e LC-ALL=C.UTF-8 \
-e TZ="America/Sao_Paulo" \
-v /home/akame/plex/config:/config \
-v /home/akame/plex/transcode:/transcode \
-v /home/akame/data/media:/data/media \
--restart=unless-stopped \
plexinc/pms-docker
# Now, in your work pc do:
ssh akame@<server_ip> -L 32400:<server_ip>:32400 -N -p 2222
And then access media-plex setup wizard at: http://localhost:32400 and create a big library at /data/media/ or split them and create one for each categories (e.g. /data/media/movies and /data/media/tvs)
Overseer
docker run -d \
--name overseerr \
-e LOG_LEVEL=debug \
-e TZ=America/Sao_Paulo \
-e PORT=5055 \
-p 5055:5055 \
-v /home/akame/overserr:/app/config \
--restart unless-stopped \
sctx/overseerr
Decluttarr
Removed stalled downloads and search for another places
mkdir /home/akame/decluttar/ && cd decluttar
touch compose.yml
Paste the contents below and run it:
services:
decluttarr:
image: ghcr.io/manimatter/decluttarr:latest
container_name: decluttarr
network_mode: host
environment:
- PUID=1000
- PGID=1000
- TZ=America/Sao_Paulo
- SSL_VERIFICATION=True
- IGNORE_PRIVATE_TRACKERS=True
- LOG_LEVEL=INFO
- REMOVE_TIMER=10
- REMOVE_FAILED=True
- REMOVE_FAILED_IMPORTS=True
- REMOVE_METADATA_MISSING=True
- REMOVE_MISSING_FILES=True
- REMOVE_ORPHANS=True
- REMOVE_SLOW=True
- REMOVE_STALLED=True
- REMOVE_UNMONITORED=True
- PERMITTED_ATTEMPTS=3
- NO_STALLED_REMOVAL_QBIT_TAG=Protected
- MIN_DOWNLOAD_SPEED=50
- RUN_PERIODIC_RESCANS={"SONARR":{"MISSING":true,"CUTOFF_UNMET":true,"MAX_CONCURRENT_SCANS":10,"MIN_DAYS_BEFORE_RESCAN":7},"RADARR":{"MISSING":true,"CUTOFF_UNMET":true,"MAX_CONCURRENT_SCANS":10,"MIN_DAYS_BEFORE_RESCAN":7}}
- FAILED_IMPORT_MESSAGE_PATTERNS=["Not a Custom Format upgrade for existing", "Not an upgrade for existing", "Invalid video file"]
- RADARR_URL=http://192.168.1.100:7878
- RADARR_KEY=key_here
- SONARR_URL=http://192.168.1.100:8989
- SONARR_KEY=key_here
- QBITTORRENT_URL=http://192.168.1.100:8080
- QBITTORRENT_USERNAME=admin
- QBITTORRENT_PASSWORD=password_here
# - READARR_URL=http://readarr:8787
# - READARR_KEY=<YOUR_API_KEY>
restart: unless-stopped
Portainer - Optional
Portainer to help administrate the containers running on the system. If needed, add WatchTower to keep the images updated.
# Create volume first
docker volume create portainer_data
docker run \
-d \
-p 8000:8000 -p 9443:9443 \
--name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data portainer/portainer-ce:lts
WatchTower - Optional
To update docker automatically
docker run -d \
--name watchtower \
--restart=unless-stopped \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
Zero Tier VPN - Optional
Zero Tier VPN, to allow you to access your media plex from anywhere.
docker run -d \
--device=/dev/net/tun \
--net=host \
--cap-add=NET_ADMIN \
--cap-add=SYS_ADMIN \
--cap-add=NET_RAW \
-v zerotier-one:<POPULATE_HERE> \
--name zerotier \
--restart=unless-stopped \
zerotier/zerotier
sudo docker exec -it zerotier zerotier-cli join <network_id>
# Accept it in your zero tier dashboard
sudo docker exec -it zerotier zerotier-cli listnetworks
# In your devices, configure custom dns to cloudflare.
Firewall rules - UFW
If you are using UFW, you somehow still need to specify firewall rules (Even with docker -p <port>:<port> bypassing it)
at /etc/ufw/applications.d/plexmediaserver add:
[plexmediaserver]
title=Plex Media Server (Standard)
description=The Plex Media Server
ports=32400/tcp|3005/tcp|5353/udp|8324/tcp|32410:32414/udp
[plexmediaserver-dlna]
title=Plex Media Server (DLNA)
description=The Plex Media Server (additional DLNA capability only)
ports=1900/udp|32469/tcp
[plexmediaserver-all]
title=Plex Media Server (Standard + DLNA)
description=The Plex Media Server (with additional DLNA capability)
ports=32400/tcp|3005/tcp|5353/udp|8324/tcp|32410:32414/udp|1900/udp|32469/tcp
Once you have defined your application file tell ufw to reload the application definitions with:
# Allow Jackett (Optional, only if jackett is used).
sudo ufw allow 9117/tcp
sudo ufw allow 9117/udp
# Allow FlareSolver.
sudo ufw allow 8191/tcp
sudo ufw allow 8191/udp
# Allow qBittorrent.
sudo ufw allow 8080/tcp
sudo ufw allow 8080/udp
# Allow Sonarr, Radarr and Prowlarr.
sudo ufw allow 7878/tcp
sudo ufw allow 7878/udp
sudo ufw allow 9696/tcp
sudo ufw allow 9696/udp
sudo ufw allow 8989/udp
sudo ufw allow 8989/tcp
# Plex ports defined in the file above.
sudo ufw app update plexmediaserver
sudo ufw allow plexmediaserver-all
# Reload
sudo ufw reload
Must do
Make sure the directories created by the docker are from the same ID and GID, in my case it’s 1000:
If your output looks like this:
drwxr-xr-x - root 10 May 21:25 data
drwxr-xr-x - root 10 May 21:21 jackett
drwxr-xr-x - root 10 May 21:25 plex
drwxr-xr-x - root 10 May 21:16 qbit
drwxr-xr-x - root 10 May 21:28 radarr
Change the permission from all of them, or more if you are using more services using:
sudo chown -R 1000:1000 /home/akame/<path_docker_is_using>/
Troubleshooting
Paths in the docker environment.
What bad thing can happen?
The biggest is that volumes defined in the dockerfile will get created if they’re not specified, this means they’ll pile up as you delete and re-create the containers. If they end up with data in them, they can consume space unexpectedly and likely in an unsuitable place. You can find a cleanup command in the helpful commands section below. This could also be mitigated by passing in an empty folder for all the volumes you don’t want to use, like /data/empty:/movies and /data/empty:/downloads. Maybe even put a file named DO NOT USE THIS FOLDER inside, to remind yourself.
Another problem is that some images are pre-configured to use the documented volumes, so you’ll need to change settings in the software inside the Docker container. Thankfully, since configuration persists outside the container this is a one time issue. You might also pick a path like /data or /media which some images already define for a specific use. It shouldn’t be a problem, but will be a little more confusing when combined with the previous issues. In the end, it is worth it for working hard links and fast moves. The consistency and simplicity are welcome side effects as well.
If you use the latest version of the abandoned RadarrSync to synchronize two Radarr instances, it depends on mapping the same path inside to a different path on the outside, for example /movies for one instance would point at /data/media/movies and the other at /data/media/movies4k. This breaks everything you’ve read above. There is no good solution, you either use the old version which isn’t as good, do your mapping in a way that is ugly and breaks hard links or just don’t use it at all.
