# ============================================================================= # MEDIA STACK - Media management, downloading, and playback services # ============================================================================= # DEPLOYMENT INSTRUCTIONS # ============================================================================= # This is one of multiple compose files in the /docker/ directory. # # Deploy ALL stacks (from /docker/ directory): # Get-ChildItem docker-compose.*.yml | ForEach-Object { docker compose -f $_ up -d } # # Deploy this stack only: # docker compose -f docker-compose.media.yml up -d # # Stop this stack: # docker compose -f docker-compose.media.yml down # # View logs for this stack: # docker compose -f docker-compose.media.yml logs -f # # IMPORTANT: Requires infra stack to be deployed first (shared networks). # ============================================================================= name: docker-media # Common configurations for re-use x-logging: &default-logging driver: "json-file" options: max-size: "10m" max-file: "3" x-security: &default-security security_opt: - no-new-privileges:true services: prowlarr: image: lscr.io/linuxserver/prowlarr:latest container_name: prowlarr restart: unless-stopped networks: media_net: ports: - "9696:9696" environment: - PUID=${PUID} - PGID=${PGID} - TZ=${TZ} volumes: - /docker/Arrs/Prowlarr/config:/config logging: *default-logging flaresolverr: image: ghcr.io/flaresolverr/flaresolverr:latest container_name: flaresolverr restart: unless-stopped networks: media_net: ports: - "127.0.0.1:8191:8191" environment: - TZ=${TZ} logging: *default-logging qbittorrent: image: lscr.io/linuxserver/qbittorrent:latest container_name: qbittorrent restart: unless-stopped networks: media_net: ports: - "56881:6881" - "56881:6881/udp" - "7070:8080" environment: - TZ=${TZ} - WEBUI_PORT=8080 - PUID=${PUID} - PGID=${PGID} volumes: - /mnt/nas-storage/data:/data - /docker/qBittorrent/config:/config logging: *default-logging radarr: image: lscr.io/linuxserver/radarr:latest container_name: radarr restart: unless-stopped networks: media_net: ports: - "7878:7878" environment: - PUID=${PUID} - PGID=${PGID} - TZ=${TZ} volumes: - /mnt/nas-storage/data/:/data - /docker/Arrs/Radarr/config:/config logging: *default-logging sonarr: image: lscr.io/linuxserver/sonarr:latest container_name: sonarr restart: unless-stopped networks: media_net: ports: - "8989:8989" environment: - PUID=${PUID} - PGID=${PGID} - TZ=${TZ} volumes: - /mnt/nas-storage/data:/data - /docker/Arrs/Sonarr/config:/config logging: *default-logging lidarr: image: ghcr.io/hotio/lidarr:nightly container_name: lidarr restart: unless-stopped networks: media_net: ports: - "8686:8686" environment: - TZ=${TZ} - PUID=${PUID} - PGID=${PGID} volumes: - /mnt/nas-storage/data:/data - /docker/Arrs/Lidarr/config:/config logging: *default-logging bazarr: image: lscr.io/linuxserver/bazarr:latest container_name: bazarr restart: unless-stopped networks: media_net: ports: - "6767:6767" environment: - PUID=${PUID} - PGID=${PGID} - TZ=${TZ} volumes: - /mnt/nas-storage/data:/data - /docker/Arrs/Bazarr/config:/config logging: *default-logging seerr: image: ghcr.io/seerr-team/seerr:latest init: true container_name: seerr environment: - LOG_LEVEL=debug - TZ=${TZ} networks: media_net: ports: - 5055:5055 volumes: - /docker/Arrs/Seerr/config:/app/config healthcheck: test: wget --no-verbose --tries=1 --spider http://localhost:5055/api/v1/status || exit 1 start_period: 20s timeout: 3s interval: 15s retries: 3 restart: unless-stopped jellyfin: image: jellyfin/jellyfin:latest container_name: jellyfin restart: unless-stopped networks: - media_net - internal_net ports: - "8096:8096" environment: - JELLYFIN_PublishedServerUrl=${JELLYFIN_URL} - TZ=${TZ} - PUID=${PUID} - PGID=${PGID} group_add: - "104" devices: - /dev/dri/renderD128:/dev/dri/renderD128 volumes: - /mnt/nas-storage/data:/data - /docker/Arrs/Jellyfin/cache:/cache - /docker/Arrs/Jellyfin/config:/config logging: *default-logging slskd: image: slskd/slskd:latest container_name: slskd restart: unless-stopped networks: media_net: ports: - "5030:5030" - "50300:50300" - "5031:5031" hostname: slskd environment: - TZ=${TZ} - SLSKD_REMOTE_CONFIGURATION=true - SLSKD_USERNAME=${SLSKD_USERNAME} - SLSKD_PASSWORD=${SLSKD_PASSWORD} volumes: - /mnt/nas-storage/data/torrents/soulsync/complete:/data/torrents/soulsync/complete - /mnt/nas-storage/data/torrents/soulsync/incomplete:/data/torrents/soulsync/incomplete - /docker/slskd:/app logging: *default-logging metube: image: ghcr.io/alexta69/metube container_name: metube restart: unless-stopped ports: - "8081:8081" volumes: - /mnt/nas-storage/data/torrents/metube:/downloads maloja: image: krateng/maloja:latest container_name: maloja restart: unless-stopped environment: - MALOJA_FORCE_PASSWORD=${MALOJA_FORCE_PASSWORD} networks: - internal_net - web_net ports: - "42010:42010" volumes: - /docker/maloja/config:/etc/maloja - /docker/maloja/data:/var/lib/maloja logging: *default-logging multi-scrobbler: image: foxxmd/multi-scrobbler:latest container_name: multi-scrobbler restart: unless-stopped networks: - internal_net ports: - "9078:9078" environment: - MALOJA_URL=${MALOJA_URL} - MALOJA_API_KEY=${MALOJA_API_KEY} - JELLYFIN_URL=${JELLYFIN_URL} - JELLYFIN_APIKEY=${JELLYFIN_APIKEY_MS} - JELLYFIN_USER=${JELLYFIN_USER} - JELLYFIN_TRANSFORMS=musicbrainz - MB_CONTACT=${MB_CONTACT} - MB_PRESETS=default,sensible,native volumes: - /docker/scrobble/config:/config logging: *default-logging networks: media_net: name: media_net external: true internal_net: name: internal_net external: true web_net: name: web_net external: true