Plex Media Server, Sonarr, Radarr, Bazarr, Jackett, qBittorrent, Tdarr, Samba (Share), Duplicati (Backup), Scrutiny (S.M.A.R.T) and WatchTower
This is an HTPC option for a private network, we will not have any direct external access, the remote access will be done by TailScale installed on an EdgeRouter-X. You can install TailScale via Docker as well.
The only open port will be from Plex, 32400 to keep remote access easier for apps and TVs.
Alternatives:
- Plex Media Server to Jellyfin: I have a lifetime license for Plex, and I still think it's the best and most complete solution, if you want to install both it won't be difficult to adjust it in Docker.
- qBittorrent to Deluge, Transmission, rTorrent: qBittorrent has the largest number of options with no need for addons, its configuration is fast and has a good performance.
Debian is a safe choice, everything should work on versions 10 and 11, but Kernel upgrade from version 12 Bookworm works better with Intel Quick Sync for HW Transcode on Plex, Jellyfin or Emby.
sudo nano /etc/ssh/sshd_config
PermitRootLogin yes
Reboot and reconnect with root user
deluser debian rm -rf /home/debian apt-get update; apt-get upgrade -y; apt-get autoremove; apt install apt-transport-https ca-certificates curl gnupg2 software-properties-common htop ncdu nano net-tools zip fdisk sl -y timedatectl set-timezone Etc/UTC
List of tz database time zones
fallocate -l 1G /swapfile chmod 600 /swapfile mkswap /swapfile swapon /swapfile
echo '/swapfile none swap sw 0 0' | tee -a /etc/fstab
sysctl vm.swappiness=10 sysctl vm.vfs_cache_pressure=50
echo 'vm.swappiness=10' | tee -a /etc/sysctl.conf echo 'vm.vfs_cache_pressure=50' | tee -a /etc/sysctl.conf
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update; apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
systemctl status docker
You should see a green status. ;)
If you're starting now, you probably have a disk with a large amount of space, after formatting this process is easier to mount.
Each disk has its own UUID.
You can find out the UUID of your disk by running blkid
, the result will be like this:
/dev/sda1: UUID="648c6531-4d62-4d3c-a0d9-074f651cdbfb" TYPE="ext4" PARTUUID="6e301172-01" /dev/sda5: UUID="5e1b25a1-498b-4bce-af47-d30aa9ea31b5" TYPE="swap" PARTUUID="6e301172-05" /dev/sdb1: LABEL="HD" UUID="CA8261F08261E205" TYPE="ntfs" PARTLABEL="HD" PARTUUID="deb852d4-a496-4b8c-9065-bec8d9c5d7e4"
If not show any addition disk, try:
fdisk -l | grep "Disk /"
The result will be like this:
Disk /dev/sdb: 20 GiB, 21474836480 bytes, 41943040 sectors Disk /dev/sda: 20 GiB, 21474836480 bytes, 41943040 sectors
fdisk /dev/sdb
n p 1 w
mkfs -t ext4 /dev/sdb1
blkid
and get UUID
nano /etc/fstab
UUID=UUID /mnt/storage auto defaults 0 0
You also need an empty folder where it will be mounted:
mkdir -p /mnt/storage
systemctl daemon-reload
Run mount -a
. If you can access your partitions and no errors appear then everything is fine.
mkdir -p /mnt/storage/{transcode,media/{tv-shows,movies},downloads/{radarr,sonarr,aria2}}/
nano .env
STORAGE_DIR=/mnt/storage DOCKER_DIR=/opt TZ=Etc/UTC PUID=0 PGID=0 PLEX_CLAIM=CLAIM_CODE
You can obtain a claim token from https://plex.tv/claim and input here. Keep in mind that the claim tokens expire within 4 minutes.
mkdir -p /opt/scrutiny/config/
nano /opt/scrutiny/config/scrutiny.yaml
Notification "urls" look like the following. For more information about service specific configuration see shoutrrr's documentation.
version: 1
web:
listen:
port: 8081
host: 0.0.0.0
#notify:
# urls:
# - "discord://token@channel"
# - "telegram://token@telegram?channels=channel-1[,channel-2,...]"
# - "pushover://shoutrrr:apiToken@userKey/?priority=1&devices=device1[,device2, ...]"
# - "slack://[botname@]token-a/token-b/token-c"
# - "smtp://username:password@host:port/?fromAddress=fromAddress&toAddresses=recipient1[,recipient2,...]"
# - "teams://token-a/token-b/token-c"
# - "gotify://gotify-host/token"
# - "pushbullet://api-token[/device/#channel/email]"
# - "ifttt://key/?events=event1[,event2,...]&value1=value1&value2=value2&value3=value3"
# - "mattermost://[username@]mattermost-host/token[/channel]"
# - "ntfy://username:password@host:port/topic"
# - "hangouts://chat.googleapis.com/v1/spaces/FOO/messages?key=bar&token=baz"
# - "zulip://bot-mail:bot-key@zulip-domain/?stream=name-or-id&topic=name"
# - "join://shoutrrr:api-key@join/?devices=device1[,device2, ...][&icon=icon][&title=title]"
# - "script:///file/path/on/disk"
# - "https://www.example.com/path"
nano docker-compose.yml
version: "3.3" services: # Watchtower watchtower: container_name: watchtower image: containrrr/watchtower:latest restart: always volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - PUID=${PUID:-1000} - PGID=${PGID:-1000} - TZ=${TZ:-Etc/UTC} - WATCHTOWER_CLEANUP=true - WATCHTOWER_INCLUDE_RESTARTING=true - WATCHTOWER_REVIVE_STOPPED=true - WATCHTOWER_SCHEDULE=0 5 * * * * - WATCHTOWER_ROLLING_RESTART=true - WATCHTOWER_INCLUDE_STOPPED=true # Plex plex: container_name: plex ports: - 32400:32400 # WebUI # - 1900:1900/udp # Plex DLNA Server # - 3005:3005 # Plex Companion # - 5353:5353/udp # Bonjour/Avahi network discovery # - 8324:8324 # Plex for Roku via Plex Companion # - 32410:32410/udp # GDM network discovery # - 32412:32412/udp # GDM network discovery # - 32413:32413/udp # GDM network discovery # - 32414:32414/udp # GDM network discovery # - 32469:32469 # Plex DLNA Server image: linuxserver/plex:latest restart: always environment: - PUID=${PUID:-1000} - PGID=${PGID:-1000} - TZ=${TZ:-Etc/UTC} - VERSION=docker - PLEX_CLAIM=${PLEX_CLAIM} volumes: - ${DOCKER_DIR:-/opt}/plex:/config - ${STORAGE_DIR:-/mnt/storage}/media:/media devices: - /dev/dri:/dev/dri # Radarr radarr: container_name: radarr ports: - 7878:7878 # WebUI image: linuxserver/radarr:latest restart: always environment: - PUID=${PUID:-1000} - PGID=${PGID:-1000} - TZ=${TZ:-Etc/UTC} volumes: - ${DOCKER_DIR:-/opt}/radarr:/config - ${STORAGE_DIR:-/mnt/storage}:/storage # Sonarr sonarr: container_name: sonarr ports: - 8989:8989 # WebUI image: linuxserver/sonarr:latest restart: always environment: - PUID=${PUID:-1000} - PGID=${PGID:-1000} - TZ=${TZ:-Etc/UTC} volumes: - ${DOCKER_DIR:-/opt}/sonarr:/config - ${STORAGE_DIR:-/mnt/storage}:/storage # Bazarr bazarr: container_name: bazarr ports: - 6767:6767 # WebUI image: linuxserver/bazarr:latest restart: always environment: - PUID=${PUID:-1000} - PGID=${PGID:-1000} - TZ=${TZ:-Etc/UTC} volumes: - ${DOCKER_DIR:-/opt}/bazarr:/config - ${STORAGE_DIR:-/mnt/storage}:/storage # Jackett jackett: container_name: jackett ports: - 9117:9117 # WebUI image: linuxserver/jackett:latest restart: always environment: - PUID=${PUID:-1000} - PGID=${PGID:-1000} - TZ=${TZ:-Etc/UTC} volumes: - ${DOCKER_DIR:-/opt}/jackett:/config # Tdarr tdarr: container_name: tdarr ports: - 8265:8265 # WebUI # - 8266:8266 # Server port # - 8267:8267 # Internal node port # - 8268:8268 # Example extra node port image: haveagitgat/tdarr:latest restart: always environment: - PUID=${PUID:-1000} - PGID=${PGID:-1000} - TZ=${TZ:-Etc/UTC} - serverIP=0.0.0.0 - serverPort=8266 - webUIPort=8265 - internalNode=true - nodeName=Tdarr volumes: - ${DOCKER_DIR:-/opt}/tdarr/server:/app/server - ${DOCKER_DIR:-/opt}/tdarr/configs:/app/configs - ${DOCKER_DIR:-/opt}/tdarr/logs:/app/logs - ${STORAGE_DIR:-/mnt/storage}:/storage devices: - /dev/dri:/dev/dri # Scrutiny scrutiny: container_name: scrutiny ports: - 8081:8081 # - 8086:8086 # InfluxDB volumes: - /run/udev:/run/udev:ro - ${DOCKER_DIR:-/opt}/scrutiny/config:/opt/scrutiny/config - ${DOCKER_DIR:-/opt}/scrutiny/influxdb:/opt/scrutiny/influxdb environment: - PUID=${PUID:-1000} - PGID=${PGID:-1000} - TZ=${TZ:-Etc/UTC} - COLLECTOR_CRON_SCHEDULE="0 0 * * 0" image: ghcr.io/analogj/scrutiny:master-omnibus cap_add: - SYS_RAWIO - SYS_ADMIN # NVMe restart: always devices: - /dev/sda:/dev/sda - /dev/sdb:/dev/sdb # qBittorrent qbittorrent: container_name: qbittorrent ports: - 8080:8080 # WebUI - 6881:6881 # Torrent - 6881:6881/udp # Torrent environment: - PUID=${PUID:-1000} - PGID=${PGID:-1000} - TZ=${TZ:-Etc/UTC} image: linuxserver/qbittorrent:latest restart: always volumes: - ${DOCKER_DIR:-/opt}/qbittorrent:/config - ${STORAGE_DIR:-/mnt/storage}:/storage # Samba samba: container_name: samba ports: - 139:139 # NetBIOS - 445:445 # TCP Stack image: dperson/samba restart: always environment: - PUID=${PUID:-0} - PGID=${PGID:-0} - TZ=${TZ:-Etc/UTC} volumes: - ${STORAGE_DIR:-/mnt/storage}:/storage command: '-s "storage;/storage;yes;no;yes;all" -p' # Duplicati duplicati: image: linuxserver/duplicati:latest container_name: duplicati ports: - 8200:8200 # WebUI environment: - PUID=${PUID:-1000} - PGID=${PGID:-1000} - TZ=${TZ:-Etc/UTC} volumes: - ${DOCKER_DIR:-/opt}/duplicati:/config - ${DOCKER_DIR:-/opt}:/docker restart: always
docker compose up -d
Wait for the complete installation of all applications, it may take several minutes.
Settings > Media Management > Importing - Check Use Hardlinks when trying to copy files from torrents that are still being seeded
Settings > Media Management > Root Folders - /storage/media/tv-shows/
Settings > Media Management > Importing - Check Use Hardlinks when trying to copy files from torrents that are still being seeded
Settings > Media Management > Root Folders - /storage/media/movies/
Options > Downloads - Default Save Path: /downloads/
If use a public trackers:
Options > BitTorrent > Enable Automatically add these trackers to new downloads:b>
Add content tracker best list from ngosang repository
- Plex: 32400
- 1900:1900/udp # Plex DLNA Server
- 3005:3005 # Plex Companion
- 5353:5353/udp # Bonjour/Avahi network discovery
- 8324:8324 # Plex for Roku via Plex Companion
- 32410:32410/udp # GDM network discovery
- 32412:32412/udp # GDM network discovery
- 32413:32413/udp # GDM network discovery
- 32414:32414/udp # GDM network discovery
- 32469:32469 # Plex DLNA Server
- qBittorrent: 8080
- 6881:6881 # Torrent
- 6881:6881/udp # Torrent
- Sonarr: 8989
- Radarr: 7878
- Bazarr: 6767
- Jackett: 9117
- Tdarr: 8265
- 8266:8266 # Server port
- 8267:8267 # Internal node port
- 8268:8268 # Example extra node port
- Duplicati: 8200
- Samba: 8200
- Scrutiny: 8200
- 8266:8266 # Server port
- https://plex.tv
- https://github.com/Sonarr/Sonarr
- https://github.com/Radarr/Radarr
- https://github.com/morpheus65535/bazarr
- https://github.com/Jackett/Jackett
- https://github.com/containrrr/watchtower
- https://github.com/ngosang/trackerslist
- https://www.qbittorrent.org
- https://www.linuxserver.io
- https://trash-guides.info
- https://github.com/dperson/samba