services: # LiveKit WebRTC Server (unchanged) livekit-server: image: livekit/livekit-server:latest container_name: voicecoach-livekit restart: unless-stopped command: - --config - /etc/livekit/livekit.yaml - --keys - "${LIVEKIT_API_KEY}: ${LIVEKIT_API_SECRET}" ports: - "7880:7880" - "7881:7881" - "50000-50100:50000-50100/udp" volumes: - ./livekit/livekit.yaml:/etc/livekit/livekit.yaml:ro networks: - voicecoach mem_limit: 512M labels: - "com.centurylinklabs.watchtower.enable=false" logging: driver: "json-file" options: max-size: "50m" max-file: "3" # Speaches: self-hosted Whisper STT + Kokoro TTS (v2 - replaces Piper + in-process Whisper) speaches: image: ghcr.io/speaches-ai/speaches:latest-cpu container_name: voicecoach-speaches restart: unless-stopped environment: - WHISPER__MODEL=Systran/faster-whisper-large-v3-turbo - WHISPER__INFERENCE_DEVICE=cpu - WHISPER__COMPUTE_TYPE=int8 - TTS__MODEL=kokoro - TTS__DEFAULT_VOICE=af_nova - TTS__LANGUAGE=en-us volumes: - /mnt/docker-data/configs/voicecoach/speaches-models:/root/.cache networks: - voicecoach mem_limit: 3G memswap_limit: 3G labels: - "com.centurylinklabs.watchtower.enable=false" healthcheck: test: ["CMD", "curl", "-sf", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 start_period: 120s logging: driver: "json-file" options: max-size: "50m" max-file: "3" # SpeechBrain Emotion Analysis (unchanged, internal only) speechbrain-service: build: context: ./speechbrain-service image: voicecoach-speechbrain:latest container_name: voicecoach-speechbrain restart: unless-stopped volumes: - /mnt/docker-data/configs/voicecoach/speechbrain-models:/app/models - /mnt/docker-data/configs/voicecoach/clips:/data/clips environment: - MODEL_DIR=/app/models networks: - voicecoach mem_limit: 3G memswap_limit: 3G labels: - "com.centurylinklabs.watchtower.enable=false" logging: driver: "json-file" options: max-size: "50m" max-file: "3" # OpenClaw VoiceCoach Agent (v2 - LLM gateway with memory/skills) voicecoach-openclaw: image: margaret-openclaw:latest container_name: voicecoach-openclaw restart: unless-stopped user: "0:0" environment: - NODE_ENV=production - HOME=/home/glyptic - USER=glyptic - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} - OPENCLAW_STATE_DIR=/home/glyptic/.voicecoach - OPENCLAW_CONFIG_PATH=/home/glyptic/.voicecoach/openclaw.json volumes: - /mnt/infrastructure/voicecoach:/home/glyptic/.voicecoach command: ["sh", "-c", "mkdir -p /home/glyptic && node --max-old-space-size=1500 /usr/local/lib/node_modules/openclaw/dist/index.js gateway --allow-unconfigured"] networks: - voicecoach mem_limit: 2G memswap_limit: 2G labels: - "com.centurylinklabs.watchtower.enable=false" logging: driver: "json-file" options: max-size: "50m" max-file: "3" # Pipecat Voice Pipeline Agent (v2 - uses Speaches + OpenClaw gateway) pipecat-agent: build: context: ./pipecat-agent image: voicecoach-pipecat:latest container_name: voicecoach-pipecat restart: unless-stopped env_file: - .env environment: - LIVEKIT_URL=ws://livekit-server:7880 - LIVEKIT_PUBLIC_URL=wss://voice.hobbs.farm - SPEACHES_URL=http://speaches:8000 - SPEECHBRAIN_URL=http://speechbrain-service:8001 - OPENCLAW_URL=http://voicecoach-openclaw:3100 - OPENCLAW_AGENT_ID=voicecoach - WHISPER_MODEL=Systran/faster-whisper-large-v3-turbo - KOKORO_VOICE=af_nova - CLIPS_DIR=/data/clips/pending volumes: - /mnt/docker-data/configs/voicecoach/clips:/data/clips depends_on: - livekit-server - speaches - speechbrain-service - voicecoach-openclaw networks: - voicecoach mem_limit: 1G memswap_limit: 1G labels: - "com.centurylinklabs.watchtower.enable=false" logging: driver: "json-file" options: max-size: "50m" max-file: "3" # Web Client (unchanged) voicecoach-web: build: context: ./web-client image: voicecoach-web:latest container_name: voicecoach-web restart: unless-stopped ports: - "8085:80" depends_on: - pipecat-agent networks: - voicecoach mem_limit: 128M labels: - "com.centurylinklabs.watchtower.enable=false" logging: driver: "json-file" options: max-size: "10m" max-file: "3" networks: voicecoach: driver: bridge