services: # LiveKit WebRTC Server 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: GPU-accelerated Whisper STT + Kokoro TTS speaches: image: ghcr.io/speaches-ai/speaches:latest-cuda container_name: voicecoach-speaches-gpu restart: unless-stopped environment: - WHISPER__INFERENCE_DEVICE=cuda - WHISPER__COMPUTE_TYPE=float16 - WHISPER__TTL=-1 volumes: - speaches-models:/home/ubuntu/.cache networks: - voicecoach deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] mem_limit: 4G labels: - "com.centurylinklabs.watchtower.enable=false" healthcheck: test: ["CMD", "curl", "-sf", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 start_period: 180s logging: driver: "json-file" options: max-size: "50m" max-file: "3" # SpeechBrain Emotion Analysis speechbrain-service: image: voicecoach-speechbrain:latest build: context: ./speechbrain-service container_name: voicecoach-speechbrain restart: unless-stopped volumes: - speechbrain-models:/app/models - voicecoach-clips:/data/clips environment: - MODEL_DIR=/app/models networks: - voicecoach mem_limit: 3G labels: - "com.centurylinklabs.watchtower.enable=false" logging: driver: "json-file" options: max-size: "50m" max-file: "3" # OpenClaw VoiceCoach Agent (LLM gateway -> Claude) 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: - ./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 labels: - "com.centurylinklabs.watchtower.enable=false" logging: driver: "json-file" options: max-size: "50m" max-file: "3" # Pipecat Voice Pipeline Agent pipecat-agent: image: voicecoach-pipecat:latest build: context: ./pipecat-agent 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 - LLM_BASE_URL=http://host.docker.internal:11434/v1 - LLM_MODEL=llama3.1:8b - WHISPER_MODEL=deepdml/faster-whisper-large-v3-turbo-ct2 - KOKORO_VOICE=af_nova - CLIPS_DIR=/data/clips/pending extra_hosts: - "host.docker.internal:host-gateway" volumes: - voicecoach-clips:/data/clips depends_on: - livekit-server - speaches - speechbrain-service networks: - voicecoach mem_limit: 1G labels: - "com.centurylinklabs.watchtower.enable=false" logging: driver: "json-file" options: max-size: "50m" max-file: "3" # Token Server + Settings API (separate from pipeline so it never goes down) token-server: image: voicecoach-pipecat:latest container_name: voicecoach-token-server restart: unless-stopped env_file: - .env environment: - LIVEKIT_PUBLIC_URL=wss://voice.hobbs.farm - SETTINGS_PATH=/data/settings.json command: ["python", "token_server.py"] volumes: - voicecoach-settings:/data networks: - voicecoach mem_limit: 256M healthcheck: test: ["CMD", "python", "-c", "import httpx; httpx.get('http://localhost:8080/health').raise_for_status()"] interval: 15s timeout: 5s retries: 3 start_period: 10s labels: - "com.centurylinklabs.watchtower.enable=false" logging: driver: "json-file" options: max-size: "10m" max-file: "3" # Web Client voicecoach-web: image: voicecoach-web:latest build: context: ./web-client container_name: voicecoach-web restart: unless-stopped ports: - "8085:80" depends_on: - token-server 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 volumes: speaches-models: speechbrain-models: voicecoach-clips: voicecoach-settings: