Files
lidify/docker-compose.yml
2025-12-25 18:58:06 -06:00

258 lines
9.0 KiB
YAML

services:
# ==============================================================================
# LIDIFY CORE APPLICATION
# ==============================================================================
# Backend API - Your Lidify Express.js server
backend:
build:
context: ./backend
dockerfile: Dockerfile
container_name: lidify_backend
environment:
# Database
DATABASE_URL: postgresql://${POSTGRES_USER:-lidifydb}:${POSTGRES_PASSWORD:-changeme}@postgres:5432/${POSTGRES_DB:-lidify}
POSTGRES_USER: ${POSTGRES_USER:-lidifydb}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme}
POSTGRES_DB: ${POSTGRES_DB:-lidify}
REDIS_URL: redis://redis:6379
# Server config
PORT: 3006
NODE_ENV: ${NODE_ENV:-production}
SESSION_SECRET: ${SESSION_SECRET:-changeme-generate-secure-key}
SETTINGS_ENCRYPTION_KEY: ${SETTINGS_ENCRYPTION_KEY:-}
# Music library (required)
# IMPORTANT: Inside Docker, music is always at /music (mounted from host MUSIC_PATH)
# Don't use ${MUSIC_PATH} here as it contains the host path, not container path
MUSIC_PATH: /music
TRANSCODE_CACHE_PATH: /app/cache/transcodes
TRANSCODE_CACHE_MAX_GB: ${TRANSCODE_CACHE_MAX_GB:-10}
# CORS
ALLOWED_ORIGINS: ${ALLOWED_ORIGINS:-http://localhost:3000,http://localhost:3030}
# Lidarr webhook callback URL - how Lidarr can reach Lidify
# Use backend:3006 for same-network communication, or external IP:3030 for external Lidarr
LIDIFY_CALLBACK_URL: ${LIDIFY_CALLBACK_URL:-http://backend:3006}
# Debug: enable extra podcast stream/cache logging
PODCAST_DEBUG: ${PODCAST_DEBUG:-0}
volumes:
- ${MUSIC_PATH:-./music}:/music
- backend_cache:/app/cache
- backend_logs:/app/logs
ports:
- "${BACKEND_PORT:-3006}:3006"
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
restart: unless-stopped
healthcheck:
test: ["CMD", "node", "healthcheck.js"]
interval: 30s
timeout: 10s
retries: 3
# Frontend Web UI - Your Lidify Next.js app
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
args:
# Prefer relative /api requests (Next.js rewrites will proxy to backend).
# If you need a custom API URL, set NEXT_PUBLIC_API_URL explicitly.
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-}
container_name: lidify_frontend
environment:
NODE_ENV: ${NODE_ENV:-production}
# Used by next.config.ts rewrites() inside the container.
# IMPORTANT: "localhost" inside a container refers to itself, not the host.
BACKEND_URL: ${BACKEND_URL:-http://backend:3006}
# Exposed to the browser; leave empty by default so the app uses /api via rewrites.
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-}
ports:
- "${FRONTEND_PORT:-3030}:3030"
depends_on:
- backend
restart: unless-stopped
healthcheck:
test: ["CMD", "node", "healthcheck.js"]
interval: 30s
timeout: 10s
retries: 3
# ==============================================================================
# INFRASTRUCTURE (Database & Cache)
# ==============================================================================
postgres:
image: postgres:16-alpine
container_name: lidify_db
environment:
POSTGRES_USER: ${POSTGRES_USER:-lidifydb}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme}
POSTGRES_DB: ${POSTGRES_DB:-lidify}
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "${POSTGRES_PORT:-5432}:5432"
restart: unless-stopped
healthcheck:
# IMPORTANT:
# pg_isready defaults to connecting to a database with the same name as the user.
# Our default user is "lidifydb" but default database is "lidify",
# so without -d this will spam logs with: FATAL: database "lidifydb" does not exist
test:
[
"CMD-SHELL",
"pg_isready -U ${POSTGRES_USER:-lidifydb} -d ${POSTGRES_DB:-lidify}",
]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
container_name: lidify_redis
ports:
- "${REDIS_PORT:-6379}:6379"
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
# ==============================================================================
# EXTERNAL SERVICES (Music Management)
# ==============================================================================
# Lidarr - Music collection manager
lidarr:
image: lscr.io/linuxserver/lidarr:latest
container_name: lidify_lidarr
environment:
- PUID=1000
- PGID=1000
- TZ=${TZ:-UTC}
volumes:
- lidarr_config:/config
- ${MUSIC_PATH:-./music}:/music
- ${DOWNLOAD_PATH:-./downloads}:/downloads
ports:
- "8686:8686"
restart: unless-stopped
# Prowlarr - Indexer manager
prowlarr:
image: lscr.io/linuxserver/prowlarr:latest
container_name: lidify_prowlarr
environment:
- PUID=1000
- PGID=1000
- TZ=${TZ:-UTC}
volumes:
- prowlarr_config:/config
ports:
- "9696:9696"
restart: unless-stopped
# FlareSolverr - Cloudflare bypass for Prowlarr
flaresolverr:
image: ghcr.io/flaresolverr/flaresolverr:latest
container_name: lidify_flaresolverr
environment:
- LOG_LEVEL=${LOG_LEVEL:-info}
- LOG_HTML=${LOG_HTML:-false}
- CAPTCHA_SOLVER=${CAPTCHA_SOLVER:-none}
- TZ=${TZ:-UTC}
ports:
- "8191:8191"
restart: unless-stopped
# NOTE: Soulseek is now handled directly by the backend using slsk-client
# No Docker container needed - downloads go straight to Singles/Artist/Album/
# qBittorrent - Torrent client
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:latest
container_name: lidify_qbittorrent
environment:
- PUID=1000
- PGID=1000
- TZ=${TZ:-UTC}
- WEBUI_PORT=8080
volumes:
- qbittorrent_config:/config
- ${MUSIC_PATH:-./music}/torrents:/music/torrents
- ${DOWNLOAD_PATH:-./downloads}:/downloads
ports:
- "8080:8080"
- "6881:6881"
- "6881:6881/udp"
restart: unless-stopped
# SABnzbd - Usenet client
sabnzbd:
image: lscr.io/linuxserver/sabnzbd:latest
container_name: lidify_sabnzbd
environment:
- PUID=1000
- PGID=1000
- TZ=${TZ:-UTC}
volumes:
- sabnzbd_config:/config
- ${DOWNLOAD_PATH:-./downloads}:/downloads
ports:
- "8085:8080"
restart: unless-stopped
# ==============================================================================
# AUDIO ANALYSIS SERVICE (Essentia)
# ==============================================================================
# Audio Analyzer - Extracts BPM, key, mood, and other audio features
audio-analyzer:
build:
context: ./services/audio-analyzer
container_name: lidify_audio_analyzer
environment:
REDIS_URL: redis://redis:6379
DATABASE_URL: postgresql://${POSTGRES_USER:-lidifydb}:${POSTGRES_PASSWORD:-changeme}@postgres:5432/${POSTGRES_DB:-lidify}
MUSIC_PATH: /music
BATCH_SIZE: ${AUDIO_ANALYSIS_BATCH_SIZE:-10}
SLEEP_INTERVAL: ${AUDIO_ANALYSIS_INTERVAL:-5}
NUM_WORKERS: ${AUDIO_ANALYSIS_WORKERS:-8}
volumes:
- ${MUSIC_PATH:-./music}:/music:ro
- audio_analyzer_models:/app/models
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
restart: unless-stopped
# Disabled by default - enable when needed
profiles:
- audio-analysis
volumes:
# Lidify core
postgres_data:
backend_cache:
backend_logs:
# Audio analysis
audio_analyzer_models:
# External services
lidarr_config:
prowlarr_config:
qbittorrent_config:
sabnzbd_config:
networks:
default:
name: lidify_network