Notes in regards to my personal media server setup
I’ve been meaning to set up an Ubuntu server to run a media server, Jenkins and Yocto as a personal project for some time. These notes are related to the media server aspect. I’ll be using docker and notes may be usefull in the future. Using docker, setting up multiple services on a linux server is easy and convenient, so this is my choice for my media server, which will be use to search for movies, games music and other media files,
MEDIA SERVER : The server setup below enmables you to automatically handle requests with Sonarr or Radarr, download them via usenet or torrent, then load them into Plex for viewing.
On of the things I love about this build is that we can run a VPN through the torrent container only (QBbittorrentVPN). We maintain our anonymity when using public torrent trackers as well as maintain normal download and upload speeds outside of the container.
System Services
Im running multiple custom service
Media Services
My mini server runs Ubuntu This mini server runs multiple services, what we call a stack:
Important Informations
PLEX
Plex is a popular media server platform that allows users to organize, stream, and access their personal media content (like movies, TV shows, music, photos, and home videos) on various devices. It provides a centralized way to manage media libraries and stream content both locally and remotely to a wide range of devices.
Key features of Plex include:
-
Media Server: Plex allows users to set up a personal media server on their computer, NAS (Network Attached Storage), or a dedicated server. The media server organizes and catalogs the user’s media files, providing rich metadata (such as cover art, summaries, actor information, and more) for a clean, easy-to-navigate interface.
-
Streaming on Multiple Devices: Plex supports streaming to a wide variety of devices, including smart TVs, smartphones (iOS and Android), tablets, streaming boxes (like Roku, Apple TV, Amazon Fire TV), gaming consoles, and web browsers. This makes it easy to access your media library from anywhere, as long as the server is running.
-
Remote Access: One of Plex’s standout features is the ability to stream your media remotely. You can access your content from outside your home network, allowing you to watch your movies, TV shows, or listen to your music while traveling or away from home.
-
Live TV and DVR: Plex offers support for live TV and DVR functionality when paired with a compatible tuner and antenna. This allows users to watch and record live over-the-air TV broadcasts, which can be stored and managed like any other media content.
-
Plex Apps and Channels: Plex offers various “channels” (which are similar to apps) that allow users to access additional content, such as web shows, podcasts, news, and streaming services. Plex also integrates with free ad-supported movies and TV shows, providing users with more viewing options.
-
Shared Libraries: Plex users can share their media libraries with friends or family, giving them access to your content while keeping separate viewing histories and watch lists. Plex also supports multi-user accounts with individual watch lists and recommendations.
-
Music and Photos: In addition to video, Plex organizes and streams music files, complete with metadata like album art and artist information. It also handles photo collections, allowing you to view and organize your photo library on all devices.
It is a versatile and comprehensive media management solution that allows users to centralize their personal media libraries and stream content across devices, both locally and remotely. With its rich features like live TV, DVR, metadata management, and support for multiple device types, Plex is widely used for home entertainment systems and is the base for me wanting to get a media server, it is fun to use and looks super profesh.
SABnzbd
SABnzbd is a program to download binary files from Usenet servers. Many people upload all sorts of interesting material to Usenet and you need a special program to get this material with the least effort. It is a free and open-source Usenet binary newsreader designed to automate the process of downloading, verifying, repairing, and unpacking files from Usenet. In short, SABnzbd is a powerful tool for automating the download and management of content from Usenet via NZB files, and it simplifies the process by handling downloading, verification, and file unpacking.
Sonarr
Sonarr is an open-source personal video recorder (PVR) software designed to help users automate the process of downloading and managing TV shows. It works by monitoring specified TV shows, checking for new episodes, and automatically downloading them from Usenet or torrent clients.
Radarr
Radarr is an open-source, movie-focused companion to Sonarr, designed to automate the process of downloading and managing movies. It works similarly to Sonarr but is specifically tailored for managing a movie collection. Radarr helps users keep track of desired movies, find high-quality versions, and download them automatically from Usenet or torrent services.
Organizr
Organizr is a web-based tool designed to consolidate access to various web applications into a single, unified dashboard. It’s particularly popular in the media server and home server communities, where users run multiple self-hosted services like Sonarr, Radarr, SABnzbd, Plex, and others. Organizr simplifies the process of managing and accessing these services by providing a centralized interface.
Grafana
Grafana is an open-source analytics and monitoring platform used to visualize and analyze metrics from various data sources in real-time. It’s widely used in industries like IT operations, DevOps, data science, and software development to monitor system performance, track business metrics, and analyze data trends. Grafana is known for its beautiful and flexible dashboards, which allow users to visualize metrics using various types of charts, graphs, heatmaps, and tables. These dashboards can be customized and arranged to display real-time data from different sources. It is widely used for infrastructure monitoring, application performance monitoring (APM), and security monitoring. Its dashboards provide real-time insights into system performance, helping teams proactively address issues. Also , Grafana includes built-in alerting functionality, allowing users to set up thresholds and get notifications when certain metrics exceed predefined limits. Alerts can be sent via email, Slack, PagerDuty, or other communication platforms.
Jackett
Jackett is an open-source tool that acts as a proxy between torrent indexers and applications like Sonarr, Radarr, and other media automation tools. Its primary purpose is to enable these applications to search for and download content from a wide variety of public and private torrent trackers. Jackett simplifies the process of searching for torrents across multiple sources and integrates them seamlessly into your media management workflows.
Prometheus
Prometheus is an open-source monitoring and alerting toolkit designed for collecting and analyzing time-series data, primarily from software systems and infrastructure. It is widely used in DevOps and cloud-native environments to monitor applications, services, and server performance metrics.
Node Exporter
Node Exporter is an open-source tool designed to expose hardware and OS-level metrics from Linux-based systems (and other operating systems) for Prometheus. It is one of the most widely used exporters in the Prometheus ecosystem, helping users monitor system metrics like CPU usage, memory consumption, disk I/O, network statistics, and more. It enables Prometheus to scrape and collect these metrics for analysis, alerting, and visualization.
Key Features of Node Exporter:
- System Metrics Exposure: Node Exporter exposes a wide range of operating system and hardware metrics, including:
- CPU usage (idle, system, user, and iowait)
- Memory usage (free, used, cached, and buffers)
- Disk I/O (read/write operations, usage, and errors)
- File system statistics (space usage, inodes)
- Network traffic (sent, received bytes, packets, errors, and dropped packets)
- Load average and system uptime
- Temperature sensors (if supported)
-
Prometheus Integration: Node Exporter works seamlessly with Prometheus, making it easy to scrape system-level metrics at regular intervals. The metrics are exposed via a simple HTTP endpoint (
/metrics
), which Prometheus can collect. - Lightweight and Minimalist: Node Exporter is designed to have a minimal impact on system performance. It runs as a lightweight daemon that exports metrics without using too many system resources.
QBittorrentVPN
Finally there’s QBittorrentVPN
qBittorrentVPN
is a Docker container or setup that combines the popular BitTorrent client qBittorrent with a VPN (Virtual Private Network) to ensure secure and private torrenting. It allows users to run qBittorrent behind a VPN, so all torrenting traffic is encrypted and routed through the VPN tunnel, preventing the user’s actual IP address from being exposed to peers in the BitTorrent network or to their Internet Service Provider (ISP).
Torrent Tracker
Last but not least, Torrent Tracker
This is an application to query different torrents indexers (i.e. PirateBay) to find differents media files. There’s plently of different pirate bay client programs out there, but this one is mine. A Django/Flex Application, configured as a docker-compose image. I basically made it with a couple of requirements in mind:
- Docker-Compose Image: So I can run the service along with other services on my media server, all managed by Portainer
- Integrated VPN: so all the requests done to the torrents indexers is encrypted and routed through the VPN tunnel, preventing the user’s actual IP address from being exposed
- QTorrentVPN Integration: So that when I find torrents to download, they are added automatically to the download queue in QBittorrent using the rest api, no more copy/pasting links left and right
Docker-Compose Configuration - Portainer Stack
This is a file with the compose yml file format.
With Docker Compose you use a YAML configuration file, known as the Compose file, to configure your application’s services, and then you create and start all the services from your configuration with the Compose CLI, in my case Portainer.
It has 10 sections, each representing a service:
- plex
- jackett
- organizr
- qbittorrentvpn
- radarr
- sabnzbd
- sonarr
- grafana
- prometheus
- node-exporter
What’s really important to configure is the volumes
section for each service. On the left of colon :
is the real path on the server, on the right is the virtual path in the image. So you need to make sure that all the paths on the left, for each service exists, has the right permissions and contains the files required by each service.
/home/storage/Configs
/home/storage/Configs/Radarr
/home/storage/Configs/Jackett
/home/storage/Configs/Organizr
/home/storage/Configs/QBittorrentVPN
/home/storage/Configs/Sabnzbd
/home/storage/Configs/Sonarr
/home/storage/Torrents
/home/storage/TorrentFiles
/home/storage/Incomplete
/home/storage/TV
/home/storage/Movies
/home/storage/Downloads
/home/storage/Downloads/Incomplete
/etc/timezone
/home/storage/Configs/Prometheus/prometheus.yml
Media Center Docker Compose File
Here’s my file
PLEX SERVER - Claiming
The PLEX_CLAIM
variable is used in the Plex Docker image to automatically claim your Plex Media Server to your Plex account when the server is first set up. This is useful when deploying Plex in a containerized environment, especially in headless or automated setups, where you may not have immediate access to the web UI for claiming the server manually.
Purpose:
When you set up Plex Media Server for the first time, Plex requires you to claim the server to link it to your Plex account. This usually involves logging into your Plex account through the server’s web UI. By using the PLEX_CLAIM
environment variable, you can bypass this manual process by providing a special claim token when the container is started, automatically linking the server to your account.
How to Use It:
- Obtain a Claim Token:
- Go to https://plex.tv/claim and log into your Plex account.
- You’ll receive a claim token in the format
claim-XXXXXXXXX
.
-
Set the
PLEX_CLAIM
Environment Variable: When you run the Plex Docker container, pass the claim token as an environment variable like this:docker run -d \ -e PLEX_CLAIM="claim-XXXXXXXXX" \ -e PLEX_UID=1000 \ -e PLEX_GID=1000 \ -v /path/to/config:/config \ -v /path/to/media:/media \ --name plex \ --network host \ plexinc/pms-docker
Replace
"claim-XXXXXXXXX"
with the claim token you obtained.
What Happens:
- The claim token allows Plex Media Server to authenticate with your Plex account and automatically register the server under your account without needing to open the web interface.
- Once the server is successfully claimed, the
PLEX_CLAIM
variable is no longer needed for future container starts, as the server remains linked to your Plex account.
Important Notes:
- Claim tokens expire after about 4 minutes, so you should generate the token just before running the Docker container.
- The
PLEX_CLAIM
variable is used only during the initial setup. After that, you won’t need to provide the token again unless you reinstall or reset the server configuration.
Ports
In a Portainer stack YAML file, the ports
section is used to define how Docker containers expose their internal ports to the host system. The format ports: - "host_port:container_port"
specifies which ports on the host should be mapped to which ports on the container. Here’s what each part of the ports
section means:
Format:
ports:
- "host_port:container_port"
host_port
: The port on the host machine that will be forwarded to the container.container_port
: The port inside the container that will be exposed to the host.
Example:
ports:
- "8080:80"
This means that:
- Port
8080
on the host will be forwarded to port80
inside the container. - When you access
http://localhost:8080
on the host, the traffic is redirected to port80
inside the container, which is typically the default HTTP port.
Why are there ports before and after the colon?
- The left side (before the colon) refers to the port on the host machine, which external clients will connect to.
- The right side (after the colon) refers to the port inside the container where the service is running.
This allows for flexibility. For example, if a containerized web application listens on port 80
inside the container, you could expose it on any port on the host (like 8080
, 3000
, or any other available port).
Ports List
application | host port | container port |
---|---|---|
portainer | 9443 | 9443 |
plex | 3000 | 3000 |
prometheus | 9292 | 9090 |
node-exporter | 9100 | 9090 |
sonarr | 8989 | 8989 |
sabnzbd | 8181 | 8080 |
sabnzbd | 9191 | 9090 |
radarr | 7878 | 7878 |
qbittorrentvpn | 8080 | 8080 |
qbittorrentvpn | 8999 | 8999 |
qbittorrentvpn | 8999 | 8999/udp |
organizr | 90 | 80 |
jackett | 9117 | 9117 |
torrents-search | 7070 | 7070 |
My Stack Definition File
services:
plex:
image: lscr.io/linuxserver/plex
container_name: plex
network_mode: host
environment:
- PUID=1000
- PGID=1000
- VERSION=docker
- PLEX_CLAIM=
volumes:
- /home/storage/Configs:/config
- /home/storage/TV:/tv
- /home/storage/Movies:/movies
restart: unless-stopped
jackett:
image: linuxserver/jackett
container_name: jackett
environment:
- PUID=1000
- PGID=1000
- TZ=America/New_York
volumes:
- /home/storage/Configs/Jackett:/config
- /home/storage/Torrents:/downloads
ports:
- 9117:9117
restart: unless-stopped
organizr:
container_name: organizr
hostname: organizr
image: organizr/organizr
restart: unless-stopped
ports:
- 90:80
volumes:
- /home/storage/Configs/Organizr:/config
environment:
- fpm=true
- branch=v2-master
- PUID=1000
- PGID=1000
- TZ=America/New_York
qbittorrentvpn:
image: markusmcnugen/qbittorrentvpn
container_name: qbittorrentvpn
privileged: true
environment:
- VPN_USERNAME= # SET YOU VPN USERNAME HERE
- VPN_PASSWORD= # SET VPN PASSWORD HERE
- PUID=1000
- PGID=1000
- WEBUI_PORT_ENV=8080
- INCOMING_PORT_ENV=8999
- VPN_ENABLED=yes
- CREATE_TUN_DEVICE=true
- LAN_NETWORK=10.0.0.0/24
- NAME_SERVERS=1.1.1.1,1.0.0.1
ports:
- 8080:8080
- 8999:8999
- 8999:8999/udp
volumes:
- /home/storage/Configs/QBittorrentVPN:/config
- /home/storage/Torrents:/downloads
- /home/storage/Incomplete:/Incomplete
- /home/storage/TorrentFiles:/TorrentFiles
- /etc/timezone:/etc/timezone:ro #This is for TimeZone
restart: unless-stopped
radarr:
image: linuxserver/radarr
container_name: radarr
environment:
- PUID=1000
- PGID=1000
- TZ=America/New_York
- UMASK_SET=022
volumes:
- /home/storage/Configs/Radarr:/config
- /home/storage/Downloads:/downloads
- /home/storage/Movies:/Movies
ports:
- 7878:7878
restart: unless-stopped
sabnzbd:
image: ghcr.io/linuxserver/sabnzbd
container_name: sabnzbd
environment:
- PUID=1000
- PGID=1000
- TZ=America/New_York
volumes:
- /home/storage/Configs/Sabnzbd:/config
- /home/storage/Downloads:/downloads
- /home/storage/Downloads/Incomplete:/incomplete-downloads #optional
ports:
- 8181:8080
- 9191:9090
restart: unless-stopped
sonarr:
image: linuxserver/sonarr
container_name: sonarr
environment:
- PUID=1000
- PGID=1000
- TZ=America/New-York
- UMASK_SET=022
volumes:
- /home/storage/Configs/Sonarr:/config
- /home/storage/Downloads:/Downloads
- /home/storage/TV:/TV
ports:
- 8989:8989
restart: unless-stopped
node-exporter:
image: quay.io/prometheus/node-exporter:latest
container_name: node-exporter
network_mode: host
environment:
- PUID=1000
- PGID=1000
- TZ=America/New_York
- UMASK_SET=022
volumes:
- /:/host:ro,rslave
ports:
- 9100:9090
restart: unless-stopped
grafana:
image: grafana/grafana
container_name: grafana
environment:
- PUID=1000
- PGID=1000
- TZ=America/New_York
- UMASK_SET=022
ports:
- 3000:3000
restart: unless-stopped
prometheus:
image: prom/prometheus
container_name: prometheus
environment:
- PUID=999
- PGID=988
- TZ=America/New_York
- UMASK_SET=022
volumes:
- /home/storage/Configs/Prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- 9292:9090
restart: unless-stopped