(K3S - 5/8) Self-host your Media Center On Kubernetes with Plex, Sonarr, Radarr, Transmission and Jackett
This article is part of the series Build your very own self-hosting platform with Raspberry Pi and Kubernetes
- Introduction
- Install Raspbian Operating-System and prepare the system for Kubernetes
- Install and configure a Kubernetes cluster with k3s to self-host applications
- Deploy NextCloud on Kuberbetes: The self-hosted Dropbox
- Self-host your Media Center On Kubernetes with Plex, Sonarr, Radarr, Transmission and Jackett
- Self-host Pi-Hole on Kubernetes and block ads and trackers at the network level
- Self-host your password manager with Bitwarden
- Deploy Prometheus and Grafana to monitor a Kubernetes cluster
Introduction
In the next article of this series, we will learn how to install and configure a Media Center onto our Kubernetes platform to automate the media aggregation and management and play our Media files. The Media Center will be composed of the following components:
- Persistence: A dedicated volume on the SSD to store the data and files
- Torrent Proxy: Jackett is a Torrent Providers Aggregator tool helping to find efficiently BitTorent files over the web
- Downloaders: Transmission is a BitTorrent client to download the files
- TV Show/Movie Media Management: We’ll use Sonarr and Radarr to automate the media aggregation. It searches, launches downloads and renames files when they go out
- Media Center/Player: Plex (server/player) will allow us to make our Media resources accessible from anywhere.
Namespace
We are going to isolate all the Kubernetes objects related to the Media Center into the namespace media
.
To create a namespace, run the following command:
1 | $ kubectl create namespace media |
Persistence
The first step consists in setting up a volume to store our media files and data required to run each component. If you followed the previous articles to install and configure a self-hosting platform using RaspberryPi and Kubernetes, you remember we have on each worker a NFS client pointing to a SSD on /mnt/ssd
.
1. Deploy the Persistent Volume (PV)
The Persistent Volume specifies the name, the size, the location and the access modes of the volume:
- The name of the PV is
media-ssd
- The size allocated is 200GB
- The location is
/mnt/ssd/media
- The access is ReadWriteOnce
Create the following file and apply it to the k8 cluster.
1 | ## media.persistentvolume.yml |
1 | $ kubectl apply -f media.persistentvolume.yml |
You can verify the PV exists with the following command:
1 | $ kubectl get pv |
2. Create the Persistent Volume Claim (PVC)
The Persistent Volume Claim is used to map a Persistent Volume to a deployment or stateful set. Unlike the PV, the PVC belongs to a namespace.
Create the following file and apply it to the k8 cluster.
1 | ## media.persistentvolumeclaim.yml |
1 | $ kubectl apply -f media.persistentvolumeclaim.yml |
You can verify the PVC exists with the following command:
1 | $ kubectl get pvc -n media |
Ingress
After the persistent volume, we are now going to deploy the ingress responsible of making accessible a service from outside the cluster by mapping an internal service:port
to a host. To choose a host, we need to configure a DNS like we did for NextCloud “nextcloud.<domain.com>” in the previous article. However, unlike NextCloud, the Media Center components have no reason to be exposed on the Internet, we can pick a host that will be resolved internally to our Nginx proxy (available at 192.168.0.240
: LoadBalancer IP). The simplest solution is to use nip.io which allows us to map an IP (in our case 192.168.0.240
) to a hostname without touching /etc/hosts
or configuring a DNS. Basically it resolves <anything>.<ip>.nip.io
by <ip>
without requiring anything else, Magic !
1. Create the file media.ingress.yaml
Create the following Ingress config file media.ingress.yaml
to map the routes to each service we will deploy right after this step:
http://media.192.168.0.240.nip.io/transmission
->transmission-transmission-openvpn:80
http://media.192.168.0.240.nip.io/sonarr
->sonarr:80
http://media.192.168.0.240.nip.io/jackett
->jackett:80
http://media.192.168.0.240.nip.io/radarr
->radarr:80
http://media.192.168.0.240.nip.io/
->plex-kube-plex:32400
1 | ## media.ingress.yaml |
2. Deploy the ingress
Deploy the Ingress by applying the file media.ingress.yaml
.
1 | $ kubectl apply -f media.ingress.yaml |
3. Confirm the Ingress is correctly deployed
Try the URL http://media.192.168.0.240.nip.io from your browser and confirm it returns the error message 503 Service Temporarily Unavailable
which is normal because we haven’t deployed anything yet.
Heml Repository - add Bananaspliff
Someone already made a very good job at creating specific Helm Charts for the all the software we wish to install in this tutorial. Add the following repository to your Helm using the following command:
1 | $ helm repo add bananaspliff https://bananaspliff.github.io/geek-charts |
BitTorrent client - Transmission over VPN
The first bit of software to install is Transmission, an open-source BitTorent client offering an API, great for integration and automation. Because many Internet providers and Governments disproves BitTorent download, we are going to deploy Transmission alongside a VPN. The image haugene/transmission-openvpn includes Transmission and supports a very large range of VPN providers (see here) to obfuscate the traffic. I will be using NordVPN but change appropriately to your need.
1. Create a Kubernetes secret to store your VPN password
We first need to safely store our VPN Provider username and password into a Kubernetes secret. Run the command using your own VPN username and password:
1 | $ kubectl create secret generic openvpn \ |
2. Write the Helm configuration
Next, we will configure the chart bananaspliff/transmission-openvpn. The default configuration can be seen by running the following command $ helm show values bananaspliff/transmission-openvpn
.
Create the file media.transmission-openvpn.values.yml
containing the following configuration.
1 | ## media.transmission-openvpn.values.yml |
2. Install the chart bananaspliff/transmission-openvpn
Execute the following command to install the chart bananaspliff/transmission-openvpn
with the above configuration onto the namespace media
.
1 | $ helm install transmission bananaspliff/transmission-openvpn \ |
After a couple of minutes, you should observe a pod named transmission-transmission-openvpn-xxx
Running.
1 | $ kubectl get pods -n media -l app=transmission-openvpn -o wide |
3. Access to Transmission Web console
Now Transmission and the Nginx Ingress routes are deployed, you should be able to access the Transmission Web console via http://media.192.168.0.240.nip.io/transmission.
Torrent Providers Aggregator- Jackett over VPN
Jackett is a Torrent Providers Aggregator which translates search queries from applications like Sonarr or Radarr into tracker-site-specific http queries, parses the html response, then sends results back to the requesting software. Because some Internet Providers might also block access to Torrent websites, I packaged a version of Jackett using a VPN connection (similar to transmission-over-vpn) accessible on Docker hub - gjeanmart/jackettvpn:arm-latest.
1. Write the Helm configuration
Let’s now configure the chart bananaspliff/jackett. The default configuration can be seen by running the following command $ helm show values bananaspliff/jackett
.
Create the file media.jackett.values.yml
containing the following configuration.
1 | ## media.jackett.values.yml |
*2. Configure VPN (only if you configured VPN_ENABLED=yes)
a. Create the following directory structure on your SSD
1 | mkdir -p /mnt/ssd/media/configs/jackett/openvpn/ |
b. Copy one OpenVPN file (usually provided by your VPN provider) into the folder /mnt/ssd/media/configs/jackett/openvpn/
c. Create a file credentials.conf
into the folder /mnt/ssd/media/configs/jackett/openvpn/
composed of two line (first one: username and second one password)
1 | <VPN_USERNAME> |
3. Pre-configure Jackett
a. Create the following directory structure on your SSD
1 | mkdir -p /mnt/ssd/media/configs/jackett/Jackett/ |
b. Create the file ServerConfig.json
into the folder /mnt/ssd/media/configs/jackett/Jackett/
with the following content:
1 | { |
4. Install the chart bananaspliff/jackett
Execute the following command to install the chart bananaspliff/jackett
with the above configuration onto the namespace media
.
1 | $ helm install jackett bananaspliff/jackett \ |
After a couple of minutes, you should observe a pod named jackett-xxx
Running.
1 | $ kubectl get pods -n media -l app=jackett -o wide |
5. Access Jackett
Go to Jackett on http://media.192.168.0.240.nip.io/jackett and try to add one or more indexers.
TV Show Library Management - Sonarr
Sonarr is a TV Show library management tool that offers multiple features:
- List all your episodes and see what’s missing
- See upcoming episodes
- Automatically search last released episodes (via Jackett) and launch download (via Transmission)
- Move downloaded files into the right directory
- Notify when a new episodes is ready (Kodi, Plex)
1. Write the Helm configuration
Let’s now configure the chart bananaspliff/sonarr. The default configuration can be seen by running the following command $ helm show values bananaspliff/sonarr
.
Create the file media.sonarr.values.yml
containing the following configuration.
1 | ### media.sonarr.values.yml |
2. Pre-configure Sonarr
a. Create the following directory structure on your SSD
1 | mkdir -p /mnt/ssd/media/configs/sonarr/ |
b. Create the file config.xml
into the folder /mnt/ssd/media/configs/sonarr/
with the following content:
1 | <Config> |
3. Install the chart bananaspliff/sonarr
Execute the following command to install the chart bananaspliff/sonarr
with the above configuration onto the namespace media
.
1 | $ helm install sonarr bananaspliff/sonarr \ |
After a couple of minutes, you should observe a pod named sonarr-xxx
Running.
1 | $ kubectl get pods -n media -l app=sonarr -o wide |
4. Access Sonarr
Go to Sonarr on http://media.192.168.0.240.nip.io/sonarr and start setting up the library automation. Refer to the wiki for more details.
- Configure the connection to Transmission into Settings / Download Client / Add (Transmission) using the hostname and port
transmission-transmission-openvpn.media:80
- Configure the connection to Jackett into Settings / Indexers / Add (Torznab / Custom) using the hostname and port
jackett.media:80
Movie Library Management - Radarr
Radarr is a Movie library management tool that offers multiple features:
- List all your movies
- Search movies (via Jackett) and launch download (via Transmission)
- Move downloaded files into the right directory
- Notify when a new movie is ready (Kodi, Plex)
1. Write the Helm configuration
Let’s now configure the chart bananaspliff/radarr. The default configuration can be seen by running the following command $ helm show values bananaspliff/radarr
.
Create the file media.radarr.values.yml
containing the following configuration.
1 | ## media.radarr.values.yml |
2. Pre-configure Radarr
a. Create the following directory structure on your SSD
1 | mkdir -p /mnt/ssd/media/configs/radarr/ |
b. Create the file config.xml
into the folder /mnt/ssd/media/configs/radarr/
with the following content:
1 | <Config> |
3. Install the chart bananaspliff/radarr
Execute the following command to install the chart bananaspliff/radarr
with the above configuration onto the namespace media
.
1 | $ helm install radarr bananaspliff/radarr \ |
After a couple of minutes, you should observe a pod named radarr-xxx
Running.
1 | $ kubectl get pods -n media -l app=radarr -o wide |
4. Access Radarr
Go to Radarr on http://media.192.168.0.240.nip.io/radarr and start setting up the library automation. Refer to the wiki for more details.
Media Server - Plex
Plex Media Server is a software to serve and stream your personal Media library (movies, TV show and music). It fetches the Media resources and builds up a catalogue accessible to any compatible players (Desktop/Mobiles) and transcodes the stream to the player.
In this section, we are going to deploy Plex Media Server (PMS) on Kubernetes using the Helm chart kube-plex.
1. Clone the charts
This Helm chart is not available via an online repository like jetstack or bananaspliff. We need to download the chart locally. Clone the following repository using git
.
1 | $ git clone https://github.com/munnerz/kube-plex.git |
2. Get a claim token
Obtain a Plex Claim Token by visiting plex.tv/claim. You need to create an account if you haven’t already one yet.
This will be used to bind your new PMS instance to your own user account automatically.
3. Create the Helm config file media.plex.values.yml
1 | ## media.plex.values.yml |
4. Install Plex using Helm
Now install Plex with Helm specifying our config file media.plex.values.yml
and the namespace media
:
1 | $ helm install plex kube-plex/charts/kube-plex/ \ |
Wait until kube-plex
(Plex Media Server) is up and running.
1 | $ kubectl get pods -n media -l app=kube-plex -o wide |
You can find the Virtual IP attributed to Plex by MetalLB (in my case 192.168.0.241
).
1 | $ kubectl get services -n media -l app=kube-plex -o wide |
5. Router config (outside access only)
If you want to access remotely to your Media library, you will need to configure a port-forwarding to allow Plex to access your PMS.
Add a route to port-forward incoming requests on port 32400
to 192.168.0.241:32400
(Plex virtual IP assigned by MetalLB).
6. Setup Plex
Try now to access (from your network) to Plex Web Player on http://192.168.0.241:32400. You should see the setup wizard :
- Click on Got It
- Select Next
You can uncheck Allow me to access my media outside my home if you only want to use Plex within your home network.
- Configure the different Libraries (movies, tv shows, music, etc.)
Our Media will be accessible from the folder /data/
.
- Click on Done
- All set! Plex will start scrapping your library (bear in mind, this can take a while)
- For outside access, you need to configure the external port used to map outside incoming requests to Plex. Go to Settings / Remote Access and check Manually specify the public to set the port
32400
(as configured in the router - Local)
Notes
- You can also access Plex from your local network via the ingress: http://media.192.168.0.240.nip.io/web
- Download the Android/iOS app and connect to your Plex account, you should automatically see your Plex Media Server with our your Media.
Conclusion
In conclusion, you now have everything you need to automate and manage your Media and enjoy watching shows, movies or just listen some music !