[UPDATED] Full guide on making a Plex server with automated torrent downloads using Docker

[UPDATED] Full guide on making a Plex server with automated torrent downloads using Docker

This week I had a bit of free time so I decided to make a Plex server with automated downloads.

Edit: Since I wrote this article, I have been able to get it more stable and simple. So, I thought I should update my article.

Disclaimer

Do not use this for anything illegal. This is for educational purpose only.

My system

I am using Ubuntu LTS for this tutorial but due to Docker being the main component, it makes it easy to replicate on other systems. I am also using a singular 1tb hard drive for this tutorial.

The stack

  • Docker is a software that produces OS-level virtualization containers allowing for easy software deployment and compatibility for many OS's.
  • Portainer is essentially just a fancy web management GUI for docker that allows easier debugging and deployment
  • Plex is a global media server with supports a lot of devices and browsers.
  • Jackett allows you to add indexers to find torrents.
  • Ombi allows people to request content.
  • Radarr is the software that connects Ombi, Plex and Jackett together to find and download movies.
  • Sonarr, like Radarr, connects Ombi, Plex and Jackett together to find and download TV Shows and Anime.
  • Transmission is a lightweight torrent client.
  • Gluetun is a lightweight VPN container that has all network traffic routed threw it.

Prerequisites

Installing Docker

You can find the installation guide here. If you want to make sure to get the latest updates for make sure to install all the prerequisites:

sudo apt-get update

sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

Next, add Docker's offical GPG key:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

Add Docker's official stable repository:

  echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Update the apt package index and Install Docker:

 sudo apt-get update

 sudo apt-get install docker-ce docker-ce-cli containerd.io

Install Portainer

You can find the installation guide here. Create a volume for Portainer data to be stored in:

sudo docker volume create portainer_data

Run it:

sudo docker run -d -p 9000:9000 -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:latest

You can see if it is working by running docker ps:

root@server:~# sudo docker ps
CONTAINER ID   IMAGE                          COMMAND                  CREATED       STATUS      PORTS                                                                                  NAMES             
de5b28eb2fa9   portainer/portainer-ce:2.9.3   "/portainer"             2 weeks ago   Up 9 days   0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 0.0.0.0:9443->9443/tcp, :::9443->9443/tcp   portainer

The filesystem

You can set up the filesystem how you want but what I have done is put all the content into /media. This is a simple secure filesystem. To make files use mkdir file.

Sonarr, Radarr, Transmission, and Sonarr will all need a common directory to be passed threw. In this case, they recommend /data.

Example of media configuration:

├── config
│   ├── jackett
│   ├── ombi
│   ├── plex
│   ├── radarr
│   ├── sonarr
│   └── transmission
└── data
    ├── media
    │   ├── Anime
    │   ├── Movies
    │   └── TV Shows
    └── torrent
        └── downloads
            ├── complete
            └── incomplete

I am also running this all under one user called media-server. If you want to create this user run this.

sudo useradd -r -m -d /opt/media-server -s /usr/sbin/nologin -g docker media-server

I also changed the owner of the directory to media-server

sudo chown -R media-sever:docker /media

If you are running multiple hard drives for your media server you can use something called Mhddfs. I have not used it but you can find more info here.

Setting up the stack in Portainer

  1. Go onto localhost:9443
  2. Make up the login credentials and log in.
  3. Click on Local then Stack.
  4. Click add stack
  5. Paste this docker-compose.yml

Tip: Portainer has a useful way to get access to logs and consoles. Click on the container and then click on the option you want.

Below I am explaining how these images work and what to configure.

Service configuration

My full script is on GitHub here.

---
version: "3.8"
services:

At the top is just basic info.

Gluetun

  gluetun:
    image: qmcgaw/gluetun:latest
    cap_add:
      - NET_ADMIN
    environment:
      - VPN_SERVICE_PROVIDER=nord
      - OPENVPN_USER=
      - OPENVPN_PASSWORD=
      - SERVER_COUNTRIES=India
    ports:
      - 9117:9117
      - 8989:8989
      - 7878:7878
      - 3579:3579
      - 9091:9091
      - 51413:51413
      - 51413:51413/udp
    restart: unless-stopped

Gluetun opens up all required ports for all the other containers. Gluetun supports all the popular VPN providers and even has the option to specify an OpenVPN file. To check the list of providers they support, check on the wiki. Even if you don't want a VPN, I recommend at least using a proxy. You can find all the info you need here. In the configurations on the other boxes when specifying IPs, use localhost.

Plex

  plex:
    image: lscr.io/linuxserver/plex:latest
    container_name: plex
    network_mode: host
    environment:
      - PUID=1000
      - PGID=1000
      - VERSION=docker
    volumes:
      - /media/config/plex:/config
      - /media/data/media/TV Shows:/tv
      - /media/data/media/Movies:/movies
    restart: unless-stopped

It is not always ideal to run these containers as root with access to the full system. You can change who runs the container with PUID AND GUID. You can find the id of the user by id USERNAME.

Plex will be started on port 32400 and will not be run threw the VPN.

Jackett

    image: linuxserver/jackett:latest
    container_name: jackett
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Africa/Abidjan
    volumes:
      - /media/config/jackett:/config
      - /media/data:/data
    network_mode: "service:gluetun"
    restart: unless-stopped

To access Jackett, use port 9117.

Sonarr and Radarr

    sonarr:
    image: linuxserver/sonarr:latest
    container_name: sonarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Africa/Abidjan
      - UMASK_SET=022 #optional
    volumes:
      - /media/config/sonarr:/config
      - /media/data:/data
    network_mode: "service:gluetun"
    restart: unless-stopped
  radarr:
    image: linuxserver/radarr:latest
    container_name: radarr
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Africa/Abidjan
      - UMASK_SET=022 #optional
    volumes:
      - /media/config/radarr:/config
      - /media/data:/data
    network_mode: "service:gluetun"
    restart: unless-stopped

Make sure your user is the owner of all the folders. When you have trouble, logs are your best friend.

Sonarr is port 8989 and Radarr is port 7878.

Ombi

  ombi:
    image: linuxserver/ombi:latest
    container_name: ombi
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Africa/Abidjan
      - BASE_URL=/ombi #optional
    volumes:
      - /media/config/ombi:/config
      - /media/data:/media
    network_mode: "service:gluetun"
    restart: unless-stopped

Pretty basic. This is the container that handles all the requests for media.

You can access this container by port 3579

Transmission

  transmission:
    image: lscr.io/linuxserver/transmission:latest
    container_name: transmission
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Africa/Abidjan
      - TRANSMISSION_WEB_HOME=/combustion-release/ #optional
#      - USER=username #optional YOU SHOULD ADD A USERNAME AND PASSWORD 
#      - PASS=password #optional
#      - WHITELIST=iplist #optional
#      - HOST_WHITELIST=dnsname list #optional
    volumes:
      - /media/config/transmission:/config
      - /media/data:/data
#     - /media/torrent/watch:/watch # any torrent file you put into /watch will be auto-downloaded
    network_mode: "service:gluetun"
    restart: unless-stopped

Transmission is a very simple lightweight torrent downloading client. I highly recommend it. I do highly recommend adding a username and password.

You can access this container by port 9091.

Starting it up

All you have to do is click 'Update the stack' and you are done setting up the server. You now have to setup up:

  • Add indexers to Jackett.
  • Adding download locations, indexers and Transmission to Sonarr and Radarr.
  • Setting up the symbolic links for Sonarr and Radarr.
  • Configure Ombi for requests for Sonarr and Radarr.

Credit

I heavily used Zac Holland's tutorial to help me set up this server. Go see his blog, he has a lot of exciting projects.

Finishing notes

I hope you enjoyed this tutorial. If you have any questions you can always leave a comment below or feel free to reach out to me on Twitter at @dingo418.