258 lines
9.0 KiB
YAML
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
|