# StreamHoard — Docker Compose deployment # # Runs alongside existing LAMP stacks without conflicts: # - Apache keeps port 80/443 # - MySQL is untouched (StreamHoard uses its own MongoDB in a container) # - StreamHoard exposes a single configurable port (default 8080) # # Usage: # cp .env.compose.example .env # # edit .env — set JWT_SECRET, ADMIN_PASSWORD, KINO_HTTP_PORT, MEDIA_ROOT_HOST # docker compose up -d # # visit http://:8080 (or whatever KINO_HTTP_PORT you set) services: mongo: image: mongo:4.4 container_name: streamhoard-mongo restart: unless-stopped volumes: - mongo-data:/data/db networks: - streamhoard # No ports exposed to host — only reachable inside streamhoard network backend: build: context: ./backend dockerfile: Dockerfile container_name: streamhoard-backend restart: unless-stopped depends_on: - mongo environment: MONGO_URL: mongodb://mongo:27017 DB_NAME: ${DB_NAME:-kino} CORS_ORIGINS: "*" JWT_SECRET: ${JWT_SECRET:?set JWT_SECRET in .env} JWT_ALG: HS256 JWT_EXPIRE_HOURS: ${JWT_EXPIRE_HOURS:-720} ADMIN_EMAIL: ${ADMIN_EMAIL:-admin@streamhoard.local} ADMIN_PASSWORD: ${ADMIN_PASSWORD:?set ADMIN_PASSWORD in .env} ADMIN_NAME: ${ADMIN_NAME:-Admin} MEDIA_ROOT: /media volumes: # Host media directory (movies, HLS, subtitles) — point at your NAS/ZFS mount - ${MEDIA_ROOT_HOST:-./media}:/media # Radarr/Sonarr report absolute file paths under this same path — must match exactly - ${MEDIA_NAS_ROOT:-/mnt/nas/video}:/mnt/nas/video:ro # Docker socket — lets the admin Services panel check/restart sibling containers - /var/run/docker.sock:/var/run/docker.sock networks: - streamhoard # No direct host port — frontend container reverse-proxies /api → backend:8001 frontend: build: context: ./frontend dockerfile: Dockerfile container_name: streamhoard-frontend restart: unless-stopped depends_on: - backend ports: # Only StreamHoard's external port. Change KINO_HTTP_PORT to avoid clashes with Apache. - "${KINO_HTTP_PORT:-8080}:80" networks: - streamhoard # ============ *arr stack + qBittorrent, all routed through gluetun (NordVPN) ============ gluetun: image: qmcgaw/gluetun container_name: streamhoard-gluetun restart: unless-stopped cap_add: - NET_ADMIN devices: - /dev/net/tun:/dev/net/tun environment: VPN_SERVICE_PROVIDER: custom VPN_TYPE: wireguard WIREGUARD_ENDPOINT_IP: ${VPN_ENDPOINT_IP:?set VPN_ENDPOINT_IP in .env} WIREGUARD_ENDPOINT_PORT: ${VPN_ENDPOINT_PORT:-51820} WIREGUARD_PUBLIC_KEY: ${VPN_PUBLIC_KEY:?set VPN_PUBLIC_KEY in .env} WIREGUARD_PRIVATE_KEY: ${VPN_PRIVATE_KEY:?set VPN_PRIVATE_KEY in .env} WIREGUARD_ADDRESSES: ${VPN_ADDRESSES:-10.5.0.2/16} FIREWALL_OUTBOUND_SUBNETS: 10.48.200.0/24 ports: - "8082:8080" # qBittorrent WebUI - "8989:8989" # Sonarr - "7878:7878" # Radarr - "9696:9696" # Prowlarr networks: - streamhoard qbittorrent: image: lscr.io/linuxserver/qbittorrent:latest container_name: streamhoard-qbittorrent restart: unless-stopped network_mode: "service:gluetun" depends_on: - gluetun environment: PUID: 999 PGID: 988 TZ: ${TZ:-America/Chicago} WEBUI_PORT: 8080 volumes: - ${STACK_CONFIG_ROOT:-/opt/streamhoard-config}/qbittorrent/qBittorrent:/config/qBittorrent - ${MEDIA_NAS_ROOT:-/mnt/nas/video}:/mnt/nas/video radarr: image: lscr.io/linuxserver/radarr:latest container_name: streamhoard-radarr restart: unless-stopped network_mode: "service:gluetun" depends_on: - gluetun environment: PUID: 999 PGID: 988 TZ: ${TZ:-America/Chicago} volumes: - ${STACK_CONFIG_ROOT:-/opt/streamhoard-config}/radarr:/config - ${MEDIA_NAS_ROOT:-/mnt/nas/video}:/mnt/nas/video sonarr: image: lscr.io/linuxserver/sonarr:latest container_name: streamhoard-sonarr restart: unless-stopped network_mode: "service:gluetun" depends_on: - gluetun environment: PUID: 999 PGID: 988 TZ: ${TZ:-America/Chicago} volumes: - ${STACK_CONFIG_ROOT:-/opt/streamhoard-config}/sonarr:/config - ${MEDIA_NAS_ROOT:-/mnt/nas/video}:/mnt/nas/video prowlarr: image: lscr.io/linuxserver/prowlarr:latest container_name: streamhoard-prowlarr restart: unless-stopped network_mode: "service:gluetun" depends_on: - gluetun environment: PUID: 999 PGID: 988 TZ: ${TZ:-America/Chicago} volumes: - ${STACK_CONFIG_ROOT:-/opt/streamhoard-config}/prowlarr:/config # ============ Docker management GUI ============ portainer: image: portainer/portainer-ce:latest container_name: streamhoard-portainer restart: unless-stopped ports: - "9443:9443" volumes: - /var/run/docker.sock:/var/run/docker.sock - portainer-data:/data networks: - streamhoard networks: streamhoard: driver: bridge volumes: mongo-data: driver: local portainer-data: driver: local