Add Navidrome and SUB/WAVE AI radio station
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.
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
services:
|
||||||
|
navidrome:
|
||||||
|
image: deluan/navidrome:latest
|
||||||
|
container_name: navidrome
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
- ND_MUSICFOLDER=/media/music
|
||||||
|
- ND_LOGLEVEL=info
|
||||||
|
- ND_PORT=4533
|
||||||
|
- TZ=America/New_York
|
||||||
|
ports:
|
||||||
|
- 4533:4533
|
||||||
|
volumes:
|
||||||
|
- /srv/navidrome/data:/data
|
||||||
|
- nas_media:/media:ro
|
||||||
|
networks:
|
||||||
|
- npm-network
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
nas_media:
|
||||||
|
external: true
|
||||||
|
|
||||||
|
networks:
|
||||||
|
npm-network:
|
||||||
|
external: true
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
# 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
|
||||||
Reference in New Issue
Block a user