# ARR Stack — Automated Media Server # https://github.com/loponai/arrstack networks: arrnetwork: name: arrnetwork ipam: config: - subnet: 172.39.0.0/24 services: # ============================================================ # GLUETUN — VPN Container # ============================================================ gluetun: image: qmcgaw/gluetun:latest container_name: gluetun cap_add: - NET_ADMIN devices: - /dev/net/tun:/dev/net/tun networks: arrnetwork: ipv4_address: ${IP_GLUETUN} ports: - 8000:8000 # Gluetun Control Server - 8080:8080 # qBittorrent WebUI - 6881:6881 # qBittorrent torrenting port - 6881:6881/udp - 9696:9696 # Prowlarr - 8191:8191 # FlareSolverr volumes: - gluetun_volume:/gluetun environment: - VPN_SERVICE_PROVIDER=${VPN_SERVICE_PROVIDER} - VPN_TYPE=${VPN_TYPE} - WIREGUARD_PRIVATE_KEY=${WIREGUARD_PRIVATE_KEY} - WIREGUARD_ADDRESSES=${WIREGUARD_ADDRESSES} - WIREGUARD_PRESHARED_KEY=${WIREGUARD_PRESHARED_KEY} - SERVER_COUNTRIES=${SERVER_COUNTRIES} - FIREWALL_VPN_INPUT_PORTS=${FIREWALL_VPN_INPUT_PORTS} - FIREWALL_OUTBOUND_SUBNETS=192.168.0.0/22 - PUID=${PUID} - PGID=${PGID} - UMASK=002 - TZ=${TZ} - BLOCK_MALICIOUS=off - HTTP_CONTROL_SERVER_ADDRESS=:8000 - HTTP_CONTROL_SERVER_LOG=on - HTTP_CONTROL_SERVER_AUTH_DEFAULT_ROLE={"auth":"none"} healthcheck: test: wget -qO /dev/null http://127.0.0.1:9999 || exit 1 interval: 20s timeout: 10s retries: 5 restart: unless-stopped # ============================================================ # QBITTORRENT — Torrent Client # ============================================================ qbittorrent: image: lscr.io/linuxserver/qbittorrent:latest container_name: qbittorrent network_mode: service:gluetun depends_on: gluetun: condition: service_healthy restart: true labels: - deunhealth.restart.on.unhealthy=true environment: - PUID=${PUID} - PGID=${PGID} - UMASK=002 - TZ=${TZ} - WEBUI_PORT=8080 - TORRENTING_PORT=${FIREWALL_VPN_INPUT_PORTS} volumes: - qbittorrent_volume:/config - /data:/data healthcheck: test: wget -q --spider http://localhost:8080 || exit 1 interval: 60s timeout: 10s retries: 3 start_period: 20s restart: unless-stopped # ============================================================ # DEUNHEALTH — Auto-restarts unhealthy containers # ============================================================ deunhealth: image: qmcgaw/deunhealth container_name: deunhealth network_mode: none environment: - LOG_LEVEL=info - HEALTH_SERVER_ADDRESS=127.0.0.1:9999 - TZ=${TZ} volumes: - /var/run/docker.sock:/var/run/docker.sock - deunhealth_volume:/config restart: always # ============================================================ # PROWLARR — Indexer Manager # ============================================================ prowlarr: image: lscr.io/linuxserver/prowlarr:latest container_name: prowlarr network_mode: service:gluetun depends_on: gluetun: condition: service_healthy restart: true environment: - PUID=${PUID} - PGID=${PGID} - UMASK=002 - TZ=${TZ} volumes: - prowlarr_volume:/config restart: unless-stopped # ============================================================ # FLARESOLVERR — Cloudflare Bypass # ============================================================ flaresolverr: image: ghcr.io/flaresolverr/flaresolverr:latest container_name: flaresolverr network_mode: service:gluetun depends_on: gluetun: condition: service_healthy restart: true volumes: - flaresolverr_volume:/config environment: - LOG_LEVEL=info - TZ=${TZ} restart: unless-stopped # ============================================================ # RADARR — Movie Manager # ============================================================ radarr: image: lscr.io/linuxserver/radarr:latest container_name: radarr environment: - PUID=${PUID} - PGID=${PGID} - UMASK=002 - TZ=${TZ} volumes: - radarr_volume:/config - /data:/data ports: - 7878:7878 networks: arrnetwork: ipv4_address: ${IP_RADARR} restart: unless-stopped # ============================================================ # SONARR — TV Show Manager # ============================================================ sonarr: image: lscr.io/linuxserver/sonarr:latest container_name: sonarr environment: - PUID=${PUID} - PGID=${PGID} - UMASK=002 - TZ=${TZ} volumes: - sonarr_volume:/config - /data:/data ports: - 8989:8989 networks: arrnetwork: ipv4_address: ${IP_SONARR} restart: unless-stopped # ============================================================ # LIDARR — Music Manager # ============================================================ lidarr: image: lscr.io/linuxserver/lidarr:latest container_name: lidarr environment: - PUID=${PUID} - PGID=${PGID} - UMASK=002 - TZ=${TZ} volumes: - lidarr_volume:/config - /data:/data ports: - 8686:8686 networks: arrnetwork: ipv4_address: ${IP_LIDARR} restart: unless-stopped # ============================================================ # BAZARR — Subtitle Manager # ============================================================ bazarr: image: lscr.io/linuxserver/bazarr:latest container_name: bazarr environment: - PUID=${PUID} - PGID=${PGID} - UMASK=002 - TZ=${TZ} volumes: - bazarr_volume:/config - /data:/data ports: - 6767:6767 networks: arrnetwork: ipv4_address: ${IP_BAZARR} restart: unless-stopped # ============================================================ # JELLYFIN — Media Server # ============================================================ jellyfin: image: lscr.io/linuxserver/jellyfin:latest container_name: jellyfin environment: - PUID=${PUID} - PGID=${PGID} - UMASK=002 - TZ=${TZ} volumes: - jellyfin_volume:/config - /data/media:/data/media ports: - 8096:8096 networks: arrnetwork: ipv4_address: ${IP_JELLYFIN} restart: unless-stopped # ============================================================ # SEERR — Request System # ============================================================ seerr: image: ghcr.io/seerr-team/seerr:v3.0.1 init: true container_name: seerr environment: - LOG_LEVEL=info - PUID=${PUID} - PGID=${PGID} - UMASK=002 - TZ=${TZ} - PORT=5055 volumes: - seerr_volume:/app/config ports: - 5055:5055 healthcheck: test: wget --no-verbose --tries=1 --spider http://localhost:5055/api/v1/settings/public || exit 1 start_period: 20s timeout: 3s interval: 15s retries: 3 networks: arrnetwork: ipv4_address: ${IP_SEERR} restart: unless-stopped # ============================================================ # LISTENARR — Audiobooks & Podcasts # ============================================================ listenarr: image: ghcr.io/listenarrs/listenarr:canary container_name: listenarr ports: - "4545:4545" environment: - PUID=${PUID} - PGID=${PGID} - UMASK=002 - TZ=${TZ} volumes: - listenarr_volume:/app/config - /data/media/audiobookshelf/books:/audiobooks - /data/torrents/books:/downloads restart: unless-stopped networks: arrnetwork: ipv4_address: ${IP_LIST} # ============================================================ # AUDIOBOOKSHELF — Audiobook / Podcast Server # ============================================================ audiobookshelf: image: ghcr.io/advplyr/audiobookshelf:latest container_name: audiobookshelf ports: - 13378:80 environment: - PUID=${PUID} - PGID=${PGID} - UMASK=002 - TZ=${TZ} volumes: - /data/media/books/audiobookshelf/books:/audiobooks - /data/media/books/audiobookshelf/podcasts:/podcasts - /data/media/books/audiobookshelf/metadata:/metadata - audiobookshelf_volume:/config restart: unless-stopped networks: arrnetwork: ipv4_address: ${IP_AUDIO} # ============================================================ # NAVIDROME — Music Streaming # ============================================================ navidrome: image: deluan/navidrome:latest container_name: navidrome ports: - 4533:4533 restart: unless-stopped environment: - ND_SCANSCHEDULE=1h - ND_LOGLEVEL=info - ND_SESSIONTIMEOUT=24h - PUID=${PUID} - PGID=${PGID} - UMASK=002 - TZ=${TZ} volumes: - navidrome_volume:/data - /data/media/music:/music:ro networks: arrnetwork: ipv4_address: ${IP_NAVI} # ============================================================ # WATCHTOWER — Automatic Image Updates # ============================================================ watchtower: image: containrrr/watchtower container_name: watchtower restart: unless-stopped environment: - DOCKER_API_VERSION=1.44 - TZ=${TZ} - PUID=${PUID} - PGID=${PGID} - WATCHTOWER_CLEANUP=${WATCHTOWER_CLEANUP} - WATCHTOWER_INCLUDE_RESTARTING=${WATCHTOWER_INCLUDE_RESTARTING} - WATCHTOWER_ROLLING_RESTARTING=${WATCHTOWER_ROLLING_RESTARTING} - WATCHTOWER_SCHEDULE=${WATCHTOWER_SCHEDULE} - WATCHTOWER_INCLUDE_STOPPED=${WATCHTOWER_INCLUDE_STOPPED} - WATCHTOWER_NOTIFICATIONS=${WATCHTOWER_NOTIFICATIONS} - WATCHTOWER_NOTIFICATIONS_HOSTNAME=${WATCHTOWER_NOTIFICATIONS_HOSTNAME} - WATCHTOWER_NOTIFICATION_EMAIL_FROM=${WATCHTOWER_NOTIFICATION_EMAIL_FROM} - WATCHTOWER_NOTIFICATION_EMAIL_TO=${WATCHTOWER_NOTIFICATION_EMAIL_TO} - WATCHTOWER_NOTIFICATION_EMAIL_SERVER=${WATCHTOWER_NOTIFICATION_EMAIL_SERVER} - WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=${WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT} - WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=${WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER} - WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=${WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD} - WATCHTOWER_NOTIFICATION_EMAIL_DELAY=${WATCHTOWER_NOTIFICATION_EMAIL_DELAY} security_opt: - no-new-privileges:true volumes: - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro - /var/run/docker.sock:/var/run/docker.sock - watchtower_volume:/config networks: arrnetwork: ipv4_address: ${IP_WATCH} sencho: image: saelix/sencho:latest container_name: sencho restart: unless-stopped ports: - "1852:1852" volumes: - /var/run/docker.sock:/var/run/docker.sock - /opt/Docker-Deployments/Sencho/data:/app/data # Change this line so the container path matches the host path. - /opt/Docker-Deployments:/opt/Docker-Deployments environment: - COMPOSE_DIR=/opt/Docker-Deployments - DATA_DIR=/app/data volumes: gluetun_volume: qbittorrent_volume: deunhealth_volume: prowlarr_volume: flaresolverr_volume: radarr_volume: sonarr_volume: lidarr_volume: bazarr_volume: jellyfin_volume: seerr_volume: listenarr_volume: audiobookshelf_volume: navidrome_volume: watchtower_volume: