Overview

This document provides guidance on deploying a headless, shared, Plex Media Server. The deployment enables users to request new media via Discord or with access to Sonarr/Radarr. I recommend you do not expose Sonarr/Radarr to anyone besides sysop.

arr sends requests to Jackett to source a torrent which is piped to Deluge for download. Once downloads complete, Deluge will extract and move them to the rclone mountpoint.

Sequence Diagram

sequenceDiagram
    User->>+Doplarr (Discord): User requests media
    Doplarr (Discord)->>+*arr Apps: Query Radarr for Movies, Sonarr for TV
    *arr Apps->>+Jackett: Query torrent trackers
    Jackett->>+*arr Apps: Return available torrents
    *arr Apps->>+Doplarr (Discord): Return available torrents
    Doplarr (Discord)->>+User: Return search results
    User->>+Doplarr (Discord): Select specific result
    Doplarr (Discord)->>+*arr Apps: Request specific media
    *arr Apps->>+Deluge: Queue specific media for download
    Deluge->>+rclone: <On Download Competion> Move media to rclone mount
    rclone->>+Plex: Pipe media files
    Plex->>+User: Serve media files

Assumptions

This document assumes you have a 100-200 level of familiarity with Ubuntu. It specifically assumes you are a reasonable & resourceful human being capable of googling things, while also understanding:

  • chmod, chown; more broadly - fixing Linux fs permissions
  • nano (or your preferred text editor)
  • apt-get
  • screen
  • ssh
  • Headless Linux deployments
  • IPv4, firewalling, routing
  • Certificate-based authentication

If you are unsure, do yourself a favor and lookup these binaries/concepts as they relate to Ubuntu before proceeding.

Infrastructure & Deployment Guide

Pre-requisite Infrastructure

  • Ubuntu host
  • Public TCP/UDP access to port 32400 (Plex)
  • PRIVATE ACCESS (only your /32 IP should be routable) to ports 7181 (SSH), 7878 (Radarr), 8989 (Sonarr), 8112 (Deluge), 9117 (Jackett)
  • 64gb (or larger) performant boot drive
  • Recommended: Several TBs of HDD attached storage for temporary storage of downloads. HDD is recommended for cost savings. Plex will serve media off the performant drive.

We will demonstrate deploying all services on a single host. Plex availability can be scaled out by deploying Plex Media Server and rclone on additional hosts in additional regions. Additional Plex regions need to be explicitly shared with your users.

Step 1: Deploy & prep the Ubuntu host

Deploy an Ubuntu host. Change the sshd port on the host for secure access:

sudo nano /etc/ssh/sshd_config

Look for #Port 22 and update it to #Port 7181, or some other lesser-used port. Restart sshd via systemctl:

sudo systemctl restart sshd

[!NOTE]
If you deployed the VM on a cloud host, ensure you properly configured the cloud firewall.

Now we need to create the mountpoints for rclone and the HDD direct-attach storage. I will name my rclone mountpoint gdrive and the HDD mountpoint local, both living in the home dir ~/:

# Make the mountpoints
mkdir ~/gdrive
mkdir ~/local

# Make the subdirectories that Plex requires.
# Do NOT change the folder names given here, nor their heirarchy. This is important
# You do NOT need to replicate this structure in ~/local. ~/local can be a clusterfuck of a data dump - it serves as only temporary holding
mkdir ~/gdrive/Media/Movies
mkdir ~/gdrive/Media/TV

# Install rclone
sudo apt-get install rclone -y

# Find the HDD disk ID
sudo lsblk -o NAME,FSTYPE,SIZE,MOUNTPOINT,LABEL

# Mount the HDD disk (this example assumes /dev/sdc)
sudo mount /dev/sdc ~/local

Now let's install/configure some other packages we will need:

1
2
3
4
5
6
7
8
9
# Install Fuse (rclone depedency)
sudo apt-get install fuse3 -y

# Update the Fuse config to allow non-root user access on mountpoints
# Use nano/your preferred text editor to uncomment the allow-other line in the conf file
sudo nano /etc/fuse.conf

# Install Deluge and the web gui
sudo apt-get install deluged deluge-web deluge-console -y

We still need to install Plex, Jackett, Sonarr, and Radarr. Find guidance for installing those packages here (no sense in me rewriting these):

  1. Plex
  2. Sonarr
  3. Radarr - Use this community install script, it's simpler than the 'official' method
  4. Jackett

Lastly, we will download the java Discord bot. We will configure this a bit later, but may as well download the bits now.
Visit the Doplarr github repo and download the latest release:

# Create a dir to host the java bits
mkdir ~/discord
cd ~/discord

# Download latest bot release
# Visit https://github.com/kiranshila/Doplarr/releases
# and grab the hyperlinks for the latest versions of config.edn and doplarr.jar
wget https://github.com/kiranshila/Doplarr/releases/download/<latest version>/doplarr.jar
wget https://github.com/kiranshila/Doplarr/releases/download/<latest version>/config.edn

# Ensure you have Java 11 or newer installed
java -version

# If you don't have Java installed, sudo apt-get install it
sudo apt-get install default-jre -y

[!NOTE]
You will not be able to complete the config.edn file just yet. We will return to this later.

Step 2: Configure rclone and mount rclone

Use rclone config to add a new profile. You should create your own OAuth credential with cloud providers, or use sftp for selfhosted storage. This guide assumes you configured an rclone profile named "gdrive".

[!NOTE]
Because we are using a headless machine, you will need to complete rclone config with your local machine. You will be prompted to specify headless authorization during rclone config. Ie - do not spam return through setup as headless authZ is not a default config option.

Use the following rclone mount command in a screen to mount the rclone storage. The params in this command minimize the rclone tax on local storage and throttle bandwidth to stay under Google's API limits. If you're not using gdrive, you should spend a considerable amount of time researching the right params for your setup and expect much trial/error testing in finding the most stable route. rclone mount will be a long running service which is why screen usage is recommended.

# rclone mount command for gdrive
rclone mount gdrive: ~/gdrive --allow-other --vfs-cache-mode off --bwlimit 15M --tpslimit 4 --tpslimit-burst 4

Detach the screen by pressing CTRL + A, D.

Step 3: Configure Plex

Plex serves at port 32400 by default. To configure the server and associate it with your plex account, we need to access localhost:32400 from the host itself - however - we are using a headless machine, therefore we need to use ssh -L to forward port 32400 to our local machine:

Return to your local machine and open a new local terminal window. Use ssh -L to forward port 32400 to your localhost:

ssh -L 32400:127.0.0.1:32400 <remote user>@<vm host> -i /path/to/cert -p 7181

[!NOTE]
-p indicates the port that sshd listens on. We changed this to 7181 in Step 1.

Now open a web browser in your local machine and navigate to https://localhost:32400. You should see the plex web app launch (after signing in) and be routed to the server setup experience.

Create 2 Plex libraries, one named Movies and one named TV. Point each library toward its respectve ~/gdrive/Media path that we setup earlier.

[!IMPORTANT]
IT IS IMPORTANT YOU SEPARATE MOVIES AND TV THIS WAY. Plex's background services responsible for processing newly-added media, finding subtitles, associating media metadata, and more, rely on this structure. Plex has separate agents for TVs and Movies.

After the initial server setup is complete, you do not need ssh -L to continue administrating the server. You can sign into the host (assuming you can route to it) from any machine and your plex account permissions will grant you remote-admin capabilities.

Step 4: Configure Deluge

Deluge serves its web gui on port 8112. Unlike Plex, we can access this gui from any remote machine (assuming the machine can route to it).

[!IMPORTANT]
Only deploy ONE instance of Deluge for your entire plex setup. If you're scaling out your plex hosts to serve media from different regions/geos, you do NOT configure Deluge (nor the Discord bot, or the arr software) on additional hosts. Because all completed media is moved to rclone's mountpoint, thus piped to Google Drive, the bits will automatically appear on other machines with the same rclone config.

Startup the deluge gui from a screen with deluge-web.

Detach screen with CTRL + A, D.

Navigate to http://[the vm host]:8112. The default password for the gui is deluge. Once signed in, change the password in preferences to something more secure.

From Deluge preferences, set the default download folder to ~/local/. Go to Plugins from the Deluge preferences and enable the Extractor and Label plugins. Close the preferences window.

At the bottom of the left-hand menu in Deluge, you should see a new section named Labels. Expand the section and right-click on the section header (gray bar that says Labels). Create 2 labels: movie and tv. You will see both labels appear in the section content.

Right-click on each label and hit Label Options. Navigate to the Folders tab and configure Moved completed to: to point toward the respective media folder in ~/gdrive. E.g., the movie label should move completed torrents to ~/gdrive/Media/Movies. This is the directory where Plex will pickup new content and serve.

Step 5: Configure Jackett

Navigate to http://[the vm host]:9117 and use the Jackett documentation to configure Jackett with torrent trackers you have access to. Every tracker has a different config process. The process is self-explanatory within the Jackett gui.

You will ultimately need the Jackett API key and the Torznab feed URLs for all of your configured indexers to complete Step 6 below:

[!TIP]
image

Step 6: Configure Sonarr/Radarr

Sonarr and Radarr are part of the arr family of apps. They help you organize media and orchestrate the search + download of content. There are TONS of tutorials and videos online for setting these apps up with Deluge and Jackett, so google it. It's dead simple. You will need the API key from Jackett (find it in the top-right corner of the Jackett gui on port 9117) and the password you set for deluge earlier.

Access Sonarr (TV Shows) at http://[the vm host]:8989

Access Radarr (Movies) at http://[the vm host]:7878

General Config Notes

In Media Management, set your Root Folder pointing toward ~/local:

[!TIP]
image

Download Client Setup Notes

When configuring Deluge as your download client in Sonarr/Radarr, be sure to fill in the Category field of the Download Client profile in arr. For Sonarr, use tv and for Radarr use movie. This will ensure the tag is auto-applied in Deluge, and completed media will be automatically moved to the appropriate Plex folder in the rclone mountpoint.

Example Download Client config:

[!TIP]
image

Indexer Setup Notes

The arr indexer profiles are what connect to Jackett. You will need 1 arr profile for each Jackett source. You can also specify indexer priority from the arr advanced settings in this menu, enabling you to prioritize which of your tracker accounts' ratios you want to hit and in what order.

[!NOTE]
Be sure you select all the appropriate categories in the indexer config. I recommend selecting every category as the arr apps function as your primary user-facing download filter. Ie, the arr apps will not resolve a request for a Windows application.

[!TIP]
image

Copy the Torznab Feed from each Jackett Indexer and input it as its own Indexer within the arr app. Both Sonarr and Radarr each need individual indexer profiles for every indexer configured in Jackett.

Example Indexer config:

[!TIP]
image

Media Profiles

I also recommend you configure the Profiles on Sonarr and Radarr. These dictate the media quality that is acceptable for download. Enabling 4K media will eat up TBs of storage quickly. Restricting low quality media will limit search results, particularly for older media where 720p (or worse) may be original quality. Think this through.

My recommended single-profile config:

[!TIP]
image

Config details:

[!TIP]
image

Step 7: Configure and run the Discord bot (Doplarr)

Return to the discord bot github repo and follow the instructions for setting the config.edn file in ~/discord. You will need the arr API keys (available from the arr gui's General Settings) and your Discord bot's key. Instructions for configuring the Discord bot app on Discord's website is in the Doplarr docs.

Your Sonarr/Radarr API keys are available in their settings gui, on the General tab.

Example config.edn below with fake API keys. Note that the leading-semicolon is comment-notation in the edn format.

{:sonarr/url "http://localhost:8989"
 :sonarr/api "75777acdee41494899123455678"
 :radarr/url "http://localhost:7878"
 :radarr/api "3627ec03028249ca88f123455678"
 ; :overseerr/url ""
 ; :overseerr/api ""
 :discord/token "MTE3MzM1NjcyMjUwMTQ2NDA5NA.GFanPn.12345678"
 ; -- Optional Settings
 ; :partial-seasons false
 :sonarr/quality-profile "HD - 720p/1080p"
 :radarr/quality-profile "HD - 720p/1080p"
 ; :radarr/rootfolder ""
 ; :sonarrr/language-profile ""
 ; :sonarr/rootfolder ""
 ; :sonarr/season-folders true
 ; :discord/max-results 10
 ; :overseerr/default-id 1
 ; :log-level :trace
 }

After you set config.edn, open a new screen session and run the java file:

java -jar doplarr.jar -Dconfig=config.edn

You should see the Discord bot join your server.

Detach the screen with CTRL + A, D.

Step 8: Share out Plex access

You're done!

Edit
Pub: 19 Nov 2023 01:49 UTC
Views: 160