services: icecast: image: libretime/icecast:2.4.4 restart: unless-stopped # Not exposed to the host: the web service proxies the stream at # /stream.mp3, so Icecast stays internal-only. If you want direct LAN # access to the raw mount, uncomment: # ports: # - "8000:8000" environment: - ICECAST_SOURCE_PASSWORD=${ICECAST_SOURCE_PASSWORD:-scannersource} - ICECAST_ADMIN_PASSWORD=${ICECAST_ADMIN_PASSWORD:-scanneradmin} - ICECAST_RELAY_PASSWORD=${ICECAST_RELAY_PASSWORD:-scannerrelay} - ICECAST_HOSTNAME=${PUBLIC_HOSTNAME:-localhost} recorder: build: ./recorder restart: unless-stopped depends_on: - icecast devices: - /dev/snd:/dev/snd - ${SCANNER_SERIAL_PORT:-/dev/ttyUSB0}:/dev/scanner environment: - ALSA_DEVICE=${ALSA_DEVICE:-hw:1,0} - SERIAL_PORT=/dev/scanner - SERIAL_BAUD=${SERIAL_BAUD:-115200} - ICECAST_HOST=icecast - ICECAST_PORT=8000 - ICECAST_MOUNT=/scanner.mp3 - ICECAST_SOURCE_PASSWORD=${ICECAST_SOURCE_PASSWORD:-scannersource} - DB_PATH=/data/scanner.db - CLIPS_DIR=/data/clips - VOX_THRESHOLD_DB=${VOX_THRESHOLD_DB:--45} - MIN_CLIP_SECONDS=${MIN_CLIP_SECONDS:-1.0} - HANG_TIME_SECONDS=${HANG_TIME_SECONDS:-2.0} - MAX_CLIP_SECONDS=${MAX_CLIP_SECONDS:-180} volumes: - ./data:/data transcriber: build: ./transcriber restart: unless-stopped environment: - DB_PATH=/data/scanner.db - CLIPS_DIR=/data/clips - WHISPER_MODEL=${WHISPER_MODEL:-small.en} - WHISPER_DEVICE=${WHISPER_DEVICE:-cuda} - WHISPER_COMPUTE=${WHISPER_COMPUTE:-int8_float16} volumes: - ./data:/data - whisper-models:/root/.cache/huggingface deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] web: build: ./web restart: unless-stopped ports: - "8080:8080" environment: - DB_PATH=/data/scanner.db - CLIPS_DIR=/data/clips - STREAM_URL=${STREAM_URL:-/stream.mp3} - ICECAST_INTERNAL_URL=http://icecast:8000${ICECAST_MOUNT:-/scanner.mp3} volumes: - ./data:/data # Cloudflare Tunnel — public access with no open router ports. # Create the tunnel at https://one.dash.cloudflare.com (Networks → Tunnels), # point its public hostname at http://web:8080, put the token in .env, # then start with: docker compose --profile tunnel up -d cloudflared: image: cloudflare/cloudflared:latest restart: unless-stopped profiles: [tunnel] command: tunnel --no-autoupdate run environment: - TUNNEL_TOKEN=${TUNNEL_TOKEN} depends_on: - web volumes: whisper-models: