Self-Hosted Media Server: Complete Homelab Guide
A self-hosted media server is rarely one app. Plex or Jellyfin plays the files, but something has to find new episodes and movies, download them, pick the right release, handle requests from the rest of the household, and fetch subtitles — without you doing any of that by hand. That "something" is a small stack of purpose-built apps, usually called the arr stack after Sonarr and Radarr, its two central pieces.
This page is the map. It explains what each piece does and how they connect. The actual setup — Docker Compose files, configuration screens, and the traps that cost real time — lives in the 8-part build series linked throughout.
The pieces, and the job each one does
| App | Job |
|---|---|
| Sonarr and Radarr | The brains. Sonarr monitors TV series, Radarr monitors movies — both watch for new episodes or films, pick a release, and import it into your library with a clean name. |
| qBittorrent + SABnzbd | The muscle. qBittorrent (always behind a VPN) handles torrents, SABnzbd handles Usenet. Sonarr and Radarr send them jobs; they don't do anything on their own. |
| Prowlarr | The eyes. Holds your indexers once and syncs them to Sonarr and Radarr, instead of configuring the same indexer list twice. |
| Seerr | The front door. A Netflix-style request UI the rest of the household actually uses, instead of anyone else opening Sonarr directly. |
| Bazarr | Finishing touches. Fetches subtitles that match the exact release sitting on disk. |
| Profilarr | Taste. Syncs curated quality-scoring rules into Sonarr and Radarr, so "best available release" means best encode, not just biggest file. |
| An AI agent (MCP) | Optional. Gives an assistant like Claude read/write access to the running stack through its own APIs, so you can ask "what's downloading" in plain language. |
| Plex, Jellyfin or Emby | Not part of this series — whatever plays the library the stack maintains. |
How a request actually flows
graph LR
U[You / family] -->|request| SEERR[Seerr]
SEERR --> SONARR[Sonarr]
SEERR --> RADARR[Radarr]
PROWLARR[Prowlarr] -->|indexers| SONARR
PROWLARR -->|indexers| RADARR
SONARR -->|send download| QB[qBittorrent + VPN]
SONARR -->|send download| SAB[SABnzbd]
RADARR --> QB
RADARR --> SAB
QB -->|completed| SONARR
SAB -->|completed| RADARR
SONARR -->|import + rename| LIB[(Media library)]
RADARR --> LIB
BAZARR[Bazarr] -->|subtitles| LIB
LIB --> PLEX[Plex / Jellyfin]
The part that matters: you never touch the downloaders directly. A request enters through Seerr, Sonarr or Radarr picks a release using the indexers Prowlarr gave them, hands it to a download client, waits for it to finish, then imports the file into the library with a clean name. The media server just sees a tidy folder appear.
The one decision that determines whether this works: storage layout
Every container in the stack needs to see your media storage through the same mount,
at the same path. The reason is hardlinks: when the downloads folder and the library
folder sit on the same filesystem and the same mount, Sonarr and Radarr "move" a
finished download by creating a hardlink — instant, free, and the torrent keeps seeding
from the original file. Split them across two separate mounts (a common Synology
mistake — different shared folders can silently land on different volumes) and every
import becomes a slow, disk-doubling full copy instead. The overview post
covers the exact folder structure, plus the PUID/PGID convention every compose file
in the series uses.
Build order, and why it isn't installation order
Most people install these in whatever order they hit a wall: get a downloader working, then Sonarr, then realize they need indexers, then Prowlarr. The series builds it the other way — brains first, then muscle, then eyes, then the rest — because Sonarr and Radarr are what every other piece plugs into. Installing a downloader before them means configuring it twice.
- Part 1 — the map, folder layout, hardlinks
- Part 2 — Sonarr and Radarr
- Part 3 — qBittorrent behind a VPN, plus SABnzbd
- Part 4 — Prowlarr
- Part 5 — Seerr
- Part 6 — Bazarr
- Part 7 — Profilarr
- Part 8 — an AI agent over MCP
Before you start
You need a box that runs Docker Compose (a Synology NAS, a Linux server, or a VM — the series isn't Synology-specific), one shared storage location for media and downloads together, and — if you want the torrent side — a VPN subscription with an OpenVPN or WireGuard config file. That last one isn't optional: a torrent client with no VPN in front of it is the one mistake this series treats as non-negotiable.
Publishing any of this outside your own network is a separate decision with its own trade-offs — see the remote access series if you want Seerr or Plex reachable from outside the house.