Navidrome indexes the existing music library on nas_media for Subsonic access. SUB/WAVE (byo-proxy variant, LAN-only) provides the Icecast broadcast, Liquidsoap crossfade/ducking, and AI DJ controller, reusing the existing Ollama instance over npm-network for the LLM and Piper for TTS.
139 lines
4.4 KiB
YAML
139 lines
4.4 KiB
YAML
# SUB/WAVE — self-hosted AI radio station.
|
|
# Deployed as the "byo-proxy" variant (no bundled Caddy): web/controller/
|
|
# broadcast bind host ports directly since this station is LAN-only for now.
|
|
# Upstream project: https://github.com/perminder-klair/subwave
|
|
#
|
|
# Values are hardcoded rather than relying on ${VAR} compose substitution,
|
|
# since Portainer git-linked stacks don't read this repo's local .env for
|
|
# that purpose (see deployment-procedures.md). ADMIN_USER/ADMIN_PASS still
|
|
# come from a real (gitignored) ./.env file next to this compose file, read
|
|
# directly by Docker's env_file mechanism.
|
|
|
|
x-logging: &default-logging
|
|
driver: json-file
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
|
|
services:
|
|
# -------------------------------------------------------------------------
|
|
# BROADCAST — icecast2 + liquidsoap in one container
|
|
# -------------------------------------------------------------------------
|
|
broadcast:
|
|
image: ghcr.io/perminder-klair/subwave-broadcast:latest
|
|
container_name: sub-wave-broadcast
|
|
restart: unless-stopped
|
|
logging: *default-logging
|
|
environment:
|
|
- TZ=America/New_York
|
|
ports:
|
|
- 7702:7702
|
|
volumes:
|
|
- /srv/subwave/state:/var/sub-wave
|
|
- /srv/subwave/logs:/var/log/liquidsoap
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "curl -fsS http://localhost:7702/status-json.xsl > /dev/null"]
|
|
interval: 5s
|
|
timeout: 3s
|
|
retries: 12
|
|
start_period: 15s
|
|
networks:
|
|
- npm-network
|
|
|
|
# -------------------------------------------------------------------------
|
|
# CONTROLLER — AI DJ brain + admin API
|
|
# -------------------------------------------------------------------------
|
|
controller:
|
|
image: ghcr.io/perminder-klair/subwave-controller:latest
|
|
container_name: sub-wave-controller
|
|
restart: unless-stopped
|
|
logging: *default-logging
|
|
depends_on:
|
|
broadcast:
|
|
condition: service_healthy
|
|
docker-socket-proxy:
|
|
condition: service_started
|
|
environment:
|
|
- NODE_ENV=production
|
|
- TZ=America/New_York
|
|
- STATE_DIR=/var/sub-wave
|
|
- SOUNDS_DIR=/sounds
|
|
- ANALYZE_URL=http://analyzer:8080
|
|
- DOCKER_HOST=tcp://docker-socket-proxy:2375
|
|
env_file:
|
|
- ./.env
|
|
ports:
|
|
- 7701:7701
|
|
volumes:
|
|
- /srv/subwave/state:/var/sub-wave
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "curl -fsS http://localhost:7701/health > /dev/null"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 6
|
|
start_period: 20s
|
|
networks:
|
|
- npm-network
|
|
|
|
# -------------------------------------------------------------------------
|
|
# DOCKER-SOCKET-PROXY — locked-down, read-only Docker API for the admin
|
|
# Stats panel. Remove this + the controller's DOCKER_HOST/depends_on entry
|
|
# for zero Docker-socket exposure.
|
|
# -------------------------------------------------------------------------
|
|
docker-socket-proxy:
|
|
image: ghcr.io/tecnativa/docker-socket-proxy:0.3.0
|
|
container_name: sub-wave-docker-proxy
|
|
restart: unless-stopped
|
|
logging: *default-logging
|
|
environment:
|
|
- CONTAINERS=1
|
|
volumes:
|
|
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
networks:
|
|
- npm-network
|
|
|
|
# -------------------------------------------------------------------------
|
|
# WEB — Next.js listener UI + admin console
|
|
# -------------------------------------------------------------------------
|
|
web:
|
|
image: ghcr.io/perminder-klair/subwave-web:latest
|
|
container_name: sub-wave-web
|
|
restart: unless-stopped
|
|
logging: *default-logging
|
|
depends_on:
|
|
controller:
|
|
condition: service_healthy
|
|
environment:
|
|
- NODE_ENV=production
|
|
- SUBWAVE_HOMEPAGE=player
|
|
- CONTROLLER_INTERNAL_URL=http://controller:7701
|
|
env_file:
|
|
- ./.env
|
|
ports:
|
|
- 7700:7700
|
|
networks:
|
|
- npm-network
|
|
|
|
# -------------------------------------------------------------------------
|
|
# ANALYZER — lean acoustic-analysis sidecar (bpm/key/loudness/outro
|
|
# detection for ending-aware crossfades). No GPU needed.
|
|
# -------------------------------------------------------------------------
|
|
analyzer:
|
|
image: ghcr.io/perminder-klair/subwave-analyzer:latest
|
|
container_name: sub-wave-analyzer
|
|
restart: unless-stopped
|
|
logging: *default-logging
|
|
mem_limit: 6g
|
|
volumes:
|
|
- /srv/subwave/state:/var/sub-wave
|
|
- analyzer-cache:/opt/analyzer/hf-cache
|
|
networks:
|
|
- npm-network
|
|
|
|
volumes:
|
|
analyzer-cache:
|
|
|
|
networks:
|
|
npm-network:
|
|
external: true
|