# 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](https://github.com/Prowlarr/Prowlarr) | `9696` | Indexer manager - feeds all *arrs | | [Radarr](https://radarr.video/) | `7878` | Movie collection manager | | [Radarr 4K](https://radarr.video/) | `7879` | Movie collection manager (4K library) | | [Sonarr](https://sonarr.tv/) | `8989` | TV series collection manager | | [Sonarr 4K](https://sonarr.tv/) | `8990` | TV series collection manager (4K library) | | [Lidarr](https://lidarr.audio/) | `8686` | Music collection manager | | [Readarr](https://readarr.com/) | `8787` | Book/audiobook collection manager | | [Bazarr](https://www.bazarr.media/) | `6767` | Subtitle manager | | [FlareSolverr](https://github.com/FlareSolverr/FlareSolverr) | `8191` | Cloudflare bypass proxy for indexers | | [Seerr](https://github.com/seerr-team/seerr) | `5055` | Media request portal (Overseerr fork) | | [Tautulli](https://tautulli.com/) | `8181` | Plex stats and monitoring | | [Kometa](https://kometa.wiki/) | `-` | Plex metadata/collections manager (runs on schedule at 03:00) | | [PlexAutoLanguages](https://github.com/RemiRigal/Plex-Auto-Languages) | `-` | Auto-sets audio/subtitle language per user, set audio/subtitle language once for a show and all episodes will change | | [ErsatzTV](https://ersatztv.org/) | `8409` | Virtual live TV channels from local media (only works for Plex Media Server owner and those in owner's 'Plex Home') | | [qBittorrent + VPN](https://github.com/DyonR/docker-qbittorrentvpn) | `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//appdata` | Per-service config (most services) | | `/arr//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. ```bash 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: ```bash 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 dedicated `arr` user if hardening the host. - `readarr` uses the `develop` tag (no stable release exists yet). - `seerr` includes a healthcheck on `/api/v1/status` - useful for Uptime Kuma monitoring. - `kometa` runs with `network_mode: host` so 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 | `` | `32400` | | Tautulli | `` | `8181` | | Radarr | `` | `7878` - root: `/data/media/movies` - profile: `HD - 720p/1080p` | | Radarr 4K | `` | `7879` - root: `/data/media/4k_movies` - profile: `Ultra-HD` | | Sonarr | `` | `8989` - root: `/data/media/tv_shows` - profile: `HD - 720p/1080p` | | Sonarr 4K | `` | `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 | |-------------|----------------| | `` | Plex → Account → [Get token](https://support.plex.tv/articles/204059436/) | | `` | [TMDb API settings](https://www.themoviedb.org/settings/api) - **required** | | `` | Tautulli → Settings → Web Interface | | `` | Radarr → Settings → General | | `` | Radarr 4K → Settings → General | | `` | Sonarr → Settings → General | | `` | Sonarr 4K → Settings → General | | `github.token` | GitHub → Settings → Developer settings → Personal access tokens | | `omdb.apikey` | [OMDb API](https://www.omdbapi.com/apikey.aspx) | | `mdblist.apikey` | [MDBList](https://mdblist.com/preferences/) | | `trakt.client_id` / `client_secret` | [Trakt API apps](https://trakt.tv/oauth/applications) | 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.