This repository documents a Docker Compose media server stack. It includes Plex, SABnzbd, Radarr, Sonarr, Bazarr, Prowlarr, Seerr, Tautulli, Maintainerr, FlareSolverr, Watchtower, and Cloudflared.
Important: Do not upload real tokens, API keys, passwords, Plex claim codes, Cloudflare tunnel tokens, Usenet credentials, or private application config folders to GitHub.
| Service | Purpose | Port |
|---|---|---|
| Plex | Media server | 32400 |
| SABnzbd | Usenet downloader | 8080 |
| Sonarr | TV show management | 8989 |
| Radarr | Movie management | 7878 |
| Bazarr | Subtitle management | 6767 |
| Prowlarr | Indexer management | 9696 |
| Seerr | Media request management | 5055 |
| Tautulli | Plex monitoring/statistics | 8181 |
| Maintainerr | Media cleanup/maintenance automation | 6246 |
| FlareSolverr | Cloudflare challenge solver for supported apps | 8191 |
| Watchtower | Automatic container updates | N/A |
| Cloudflared | Cloudflare tunnel | N/A |
This setup uses a main media drive and a separate SSD for fast staging/unpacking.
Example:
NAME SIZE MOUNTPOINT
sda 50G /
sdb1 500G /mnt/media_ssd
sdc1 18.2T /mnt/media| Path | Purpose |
|---|---|
/ |
Main OS drive |
/mnt/media_ssd |
Fast SSD staging/unpacking location for downloads |
/mnt/media |
Main long-term media library |
~/stack |
Docker Compose stack and container config folders |
Example Docker stack location:
~/stackExample stack directory:
~/stack/
├── bazarr/
├── data/
├── docker-compose.yml
├── maintainerr/
├── plex/
├── prowlarr/
├── radarr/
├── sabnzbd/
├── seerr/
├── sonarr/
└── tautulli/The config folders are created and used by the containers. They should not be uploaded to GitHub because they may contain private settings, API keys, database files, or credentials.
Copy .env.example to .env:
cp .env.example .envThen edit it:
nano .envExample:
PUID=1000
PGID=1000
TZ=America/Chicago
ROOT=/home/YOUR_USERNAME/stack
PLEX_CLAIM=
CLOUDFLARE_TUNNEL_TOKEN=Check your user and group ID with:
idROOT should point to the folder where your app config folders live.
PLEX_CLAIM is optional and should only be used during initial Plex setup.
CLOUDFLARE_TUNNEL_TOKEN should never be committed to GitHub.
This compose file uses an external Docker network called media.
Create it before starting the stack:
docker network create mediaYou only need to do this once.
From the stack folder:
cd ~/stack
docker compose up -dCheck running containers:
docker psCheck logs for a container:
docker logs -f plexExample:
docker logs -f sabnzbdReplace SERVER-IP with your server IP address.
| Service | URL Example |
|---|---|
| Prowlarr | http://SERVER-IP:9696 |
| SABnzbd | http://SERVER-IP:8080 |
| Sonarr | http://SERVER-IP:8989 |
| Radarr | http://SERVER-IP:7878 |
| Bazarr | http://SERVER-IP:6767 |
| Plex | http://SERVER-IP:32400/web |
| FlareSolverr | http://SERVER-IP:8191 |
| Seerr | http://SERVER-IP:5055 |
| Tautulli | http://SERVER-IP:8181 |
| Maintainerr | http://SERVER-IP:6246 |
Inside most containers, the main media folder is mapped like this:
/mnt/media:/dataThat means inside containers, the media path is usually:
/dataSABnzbd also has access to the SSD staging drive:
/mnt/media_ssd:/mnt/media_ssdThis allows downloads and unpacking to happen on the SSD before completed media is moved to the large media drive.
This stack includes Watchtower for scheduled automatic container updates.
Manual update method:
cd ~/stack
docker compose pull
docker compose up -dRemove unused old images:
docker image prune -fdocker compose configdocker restart plexcd ~/stack
docker compose restartcd ~/stack
docker compose downcd ~/stack
docker compose up -dBefore uploading to GitHub, make sure you do not upload:
.env- Plex claim codes
- Cloudflare tunnel tokens
- API keys
- Passwords
- Usenet provider credentials
- Indexer credentials
- App database/config folders
- Backup ZIPs that may contain private settings or API keys
The included .gitignore is designed to help prevent accidental uploads of private files.