7.8 KiB
Arr Stack
Self-hosted media automation stack running via individual Docker Compose files, organized per service.
Repository Structure
arr-stack/
├── bazarr/ docker-compose.yaml
├── ersatz/ docker-compose.yaml
├── flaresolverr/ docker-compose.yaml
├── kometa/ docker-compose.yaml
├── lidarr/ docker-compose.yaml
├── plexautolanguages/ docker-compose.yaml
├── prowlarr/ docker-compose.yaml
├── qbit-vpn/ docker-compose.yaml
├── radarr/ docker-compose.yaml
├── radarr4k/ docker-compose.yaml
├── readarr/ docker-compose.yaml
├── seerr/ docker-compose.yaml
├── sonarr/ docker-compose.yaml
├── sonarr4k/ docker-compose.yaml
├── tautulli/ docker-compose.yaml
├── refresh-radarr.sh
├── refresh-radarr4k.sh
├── refresh-sonarr.sh
└── refresh-sonarr4k.sh
Services
| Service | Port | Purpose |
|---|---|---|
| Prowlarr | 9696 |
Indexer manager - feeds all *arrs |
| Radarr | 7878 |
Movie collection manager |
| Radarr 4K | 7879 |
Movie collection manager (4K library) |
| Sonarr | 8989 |
TV series collection manager |
| Sonarr 4K | 8990 |
TV series collection manager (4K library) |
| Lidarr | 8686 |
Music collection manager |
| Readarr | 8787 |
Book/audiobook collection manager |
| Bazarr | 6767 |
Subtitle manager |
| FlareSolverr | 8191 |
Cloudflare bypass proxy for indexers |
| Seerr | 5055 |
Media request portal (Overseerr fork) |
| Tautulli | 8181 |
Plex stats and monitoring |
| Kometa | - |
Plex metadata/collections manager (runs on schedule at 03:00) |
| PlexAutoLanguages | - |
Auto-sets audio/subtitle language per user, set audio/subtitle language once for a show and all episodes will change |
| ErsatzTV | 8409 |
Virtual live TV channels from local media (only works for Plex Media Server owner and those in owner's 'Plex Home') |
| qBittorrent + VPN | 8080 / 8443 |
Torrent client behind OpenVPN; HTTPS via sidecar Nginx |
Data Layout
All services share a common volume structure on the host:
| Host Path | Purpose |
|---|---|
/data |
Unified media root (movies, tv, music, books, downloads) |
/arr/<service>/appdata |
Per-service config (most services) |
/arr/<service>/config |
Per-service config (some services use /config naming) |
Having all services share /data means completed downloads are visible to the *arrs without cross-device moves.
Refresh Scripts
The four refresh scripts hit their respective service's API to trigger a metadata refresh, missing media search, and RSS sync in sequence. Useful after library changes or to kick a stalled queue. NOTE: Arrs apps only search one time after adding a movie or tv-show. Manual refresh required if not using these scripts.
| Script | Target | Port |
|---|---|---|
refresh-radarr.sh |
Radarr | 7878 |
refresh-radarr4k.sh |
Radarr 4K | 7879 |
refresh-sonarr.sh |
Sonarr | 8989 |
refresh-sonarr4k.sh |
Sonarr 4K | 8990 |
Before using, set API_KEY at the top of each script to the API key found under Settings → General in the respective service UI.
chmod +x refresh-*.sh
./refresh-radarr.sh
qBittorrent + VPN
The qbit-vpn stack runs two containers: the torrent client behind OpenVPN (dyonr/qbittorrentvpn) and a sidecar Nginx that terminates HTTPS on port 8443 and proxies to the qBittorrent web UI. The VPN credentials are in the compose file - keep that file out of public repos.
Ports:
8080- qBittorrent web UI (HTTP, LAN only)8443- qBittorrent web UI (HTTPS via Nginx sidecar)8999/8999/udp- torrent peer traffic
SSL certs for Nginx are bind-mounted from /arr/qbittorrent/ssl. The Nginx config is at /arr/qbittorrent/nginx.conf.
Starting / Stopping Services
Each service is independent. From its directory:
docker compose up -d
docker compose down
docker compose pull && docker compose up -d # update
Notes
- All *arr services run as
PUID=0 / PGID=0(root). This is due to how SMB shares are mounted to Proxmox LXCs, requiring 'PUID / PGID = 0'. If running in a VM (recommended), consider dropping to a dedicatedarruser if hardening the host. readarruses thedeveloptag (no stable release exists yet).seerrincludes a healthcheck on/api/v1/status- useful for Uptime Kuma monitoring.kometaruns withnetwork_mode: hostso it can reach other services on localhost.- FlareSolverr's port and log level are configurable via
.env(PORT,LOG_LEVEL).
Kometa Configuration (kometa/config/config.yml)
The Kometa config is templated - copy config.yml.template to config.yml and fill in credentials before first run.
Active Libraries
| Library | Collections | Overlays |
|---|---|---|
| Movies | basic, imdb defaults |
media_info.yml, audience_rating.yml |
| TV Shows | basic, imdb defaults |
media_info.yml, audience_rating.yml |
| Music | config/Music.yml (local) |
- |
4K Movies and 4K TV Shows libraries are defined but commented out. Uncomment and add to the libraries: block if/when those Plex libraries are active.
Connected Services
| Service | Placeholder | Port |
|---|---|---|
| Plex | <YOUR_PLEX_IP> |
32400 |
| Tautulli | <YOUR_TAUTULLI_IP> |
8181 |
| Radarr | <YOUR_RADARR_IP> |
7878 - root: /data/media/movies - profile: HD - 720p/1080p |
| Radarr 4K | <YOUR_RADARR_4K_IP> |
7879 - root: /data/media/4k_movies - profile: Ultra-HD |
| Sonarr | <YOUR_SONARR_IP> |
8989 - root: /data/media/tv_shows - profile: HD - 720p/1080p |
| Sonarr 4K | <YOUR_SONARR_4K_IP> |
8990 - root: /data/media/4ktv_shows - profile: Ultra-HD |
Credentials to Fill In
All of the following must be set in config.yml before Kometa will run. Find them in each service's UI under Settings → General → API Key (or equivalent):
| Placeholder | Where to get it |
|---|---|
<YOUR_PLEX_TOKEN> |
Plex → Account → Get token |
<YOUR_TMDB_API_KEY> |
TMDb API settings - required |
<YOUR_TAUTULLI_API_KEY> |
Tautulli → Settings → Web Interface |
<YOUR_RADARR_API_KEY> |
Radarr → Settings → General |
<YOUR_RADARR_4K_API_KEY> |
Radarr 4K → Settings → General |
<YOUR_SONARR_API_KEY> |
Sonarr → Settings → General |
<YOUR_SONARR_4K_API_KEY> |
Sonarr 4K → Settings → General |
github.token |
GitHub → Settings → Developer settings → Personal access tokens |
omdb.apikey |
OMDb API |
mdblist.apikey |
MDBList |
trakt.client_id / client_secret |
Trakt API apps |
Notifiarr, Gotify, AniDB, and MAL are stubbed out but disabled - fill in only if you use them.
Custom Overlays
Local overlay files are expected at:
kometa/config/overlays/media_info.yml
kometa/config/overlays/audience_rating.yml
And the Music collection file at:
kometa/config/Music.yml
These are not included in this repo - create or source them separately.