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 dns_search: [""] 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) # NOTE: No WHISPER__MODEL or TTS__* env vars - WhisperConfig has no 'model' field in this version. # Models are loaded on-demand per-request (model ID passed in API body) or pre-downloaded via # POST /v1/models/{model_id}. TTS model/voice are also per-request in POST /v1/audio/speech body. # Volume must map to /home/ubuntu/.cache (container runs as 'ubuntu', not root). speaches: image: ghcr.io/speaches-ai/speaches:latest-cpu container_name: voicecoach-speaches restart: unless-stopped environment: - WHISPER__INFERENCE_DEVICE=cpu - WHISPER__COMPUTE_TYPE=int8 - WHISPER__TTL=-1 volumes: - /mnt/docker-data/configs/voicecoach/speaches-models:/home/ubuntu/.cache dns_search: [""] 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 dns_search: [""] 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" ports: - "3100:3100" 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"] dns_search: [""] 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://192.168.86.150:8000 - SPEECHBRAIN_URL=http://speechbrain-service:8001 - OPENCLAW_URL=http://voicecoach-openclaw:3100 - OPENCLAW_AGENT_ID=voicecoach - WHISPER_MODEL=deepdml/faster-whisper-large-v3-turbo-ct2 - KOKORO_VOICE=af_nova - CLIPS_DIR=/data/clips/pending volumes: - /mnt/docker-data/configs/voicecoach/clips:/data/clips depends_on: - livekit-server - speechbrain-service - voicecoach-openclaw dns_search: [""] 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 dns_search: [""] 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