services: # flynn: # build: . # container_name: flynn # restart: unless-stopped # ports: # - "18800:18800" # volumes: # # Persistent data (sessions DB, memory store) # - flynn-data:/data # # Mount your config file # - ./config/default.yaml:/config/config.yaml:ro # environment: # # Required: at least one model provider API key # - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-} # # Optional: additional provider keys # - OPENAI_API_KEY=${OPENAI_API_KEY:-} # - OPENROUTER_API_KEY=${OPENROUTER_API_KEY:-} # - GOOGLE_API_KEY=${GOOGLE_API_KEY:-} # # Optional: Telegram integration # - FLYNN_TELEGRAM_TOKEN=${FLYNN_TELEGRAM_TOKEN:-} # # Optional: Discord integration # - DISCORD_BOT_TOKEN=${DISCORD_BOT_TOKEN:-} # # Optional: Gateway auth token # - FLYNN_SERVER_TOKEN=${FLYNN_SERVER_TOKEN:-} # healthcheck: # test: ["CMD", "wget", "-qO-", "http://localhost:18800/"] # interval: 30s # timeout: 5s # start_period: 15s # retries: 3 # One-shot init: download whisper models into the shared volume if missing. # The base image only ships ggml-base.en.bin; the servers below require: # - ggml-medium.bin for the CPU server # - ggml-small.bin for the GPU server (small fits in the limited VRAM left after gemma) whisper-init: image: ghcr.io/ggml-org/whisper.cpp@sha256:672650b5e67f9cb86af7ac6e09dea8eac12a024086e1e5c0172fdccf336aba09 container_name: whisper-init profiles: ["voice", "voice-cpu-backup"] restart: "no" volumes: - whisper-models:/app/models entrypoint: ["sh", "-c"] command: - | set -e for m in medium small base; do if [ -f /app/models/ggml-$$m.bin ]; then echo "Model ggml-$$m.bin already present, skipping download." else echo "Downloading ggml-$$m.bin..." sh /app/models/download-ggml-model.sh $$m /app/models fi done # Manual GPU whisper.cpp fallback: NVIDIA RTX 5070 Ti via CUDA (Blackwell sm_120). # Kept out of the normal `voice` profile because the OpenVINO NPU Whisper # service is the default and this container consumes GPU resources. # # The official `ghcr.io/ggml-org/whisper.cpp:main-cuda` ships kernels only # for sm_75/80/86/90 and fails to init CUDA on Blackwell. We build a custom # image with `CMAKE_CUDA_ARCHITECTURES=120` from the local Dockerfile. # Build manually with: docker build -t whisper.cpp:cuda-blackwell ./whisper-cuda-blackwell # Or `docker compose --profile voice-gpu build whisper-server-gpu`. whisper-server-gpu: image: whisper.cpp:cuda-blackwell build: context: ./whisper-cuda-blackwell dockerfile: Dockerfile container_name: whisper-server-gpu restart: unless-stopped profiles: ["voice-gpu"] ports: - "18801:8080" volumes: - whisper-models:/app/models entrypoint: ["whisper-server"] command: - --model - /app/models/ggml-base.bin - --host - 0.0.0.0 - --port - "8080" - --convert - --language - auto - --inference-path - /v1/audio/transcriptions deploy: resources: reservations: devices: - driver: nvidia count: 1 capabilities: [gpu] depends_on: whisper-init: condition: service_completed_successfully healthcheck: test: [ "CMD-SHELL", "curl -f http://localhost:8080/ >/dev/null 2>&1 || exit 1", ] interval: 30s timeout: 5s start_period: 30s retries: 3 labels: agentmon.monitor: "true" agentmon.role: "voice" agentmon.port: "18801" # Experimental OpenVINO GenAI Whisper server using the Intel NPU. # This is not whisper.cpp; it implements the same OpenAI-style # /v1/audio/transcriptions route using OpenVINO WhisperPipeline on NPU. # Host requirements: intel-npu-driver-bin installed, /dev/accel/accel0 present, # and the host NPU Level Zero driver/compiler libraries mounted below. whisper-server-npu: image: whisper-openvino-npu:local build: context: ./whisper-openvino-npu dockerfile: Dockerfile container_name: whisper-server-npu restart: unless-stopped profiles: ["voice"] ports: - "18816:8080" devices: - /dev/accel/accel0:/dev/accel/accel0 group_add: - "987" # host render group gid on willlaptop environment: - WHISPER_DEVICE=NPU - WHISPER_MODEL_DIR=/models/whisper-tiny-fp16-ov - LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu - ZE_ENABLE_ALT_DRIVERS=/usr/lib/x86_64-linux-gnu/libze_intel_npu.so.1 volumes: - /home/will/.cache/openvino-models/whisper-tiny-fp16-ov:/models/whisper-tiny-fp16-ov:ro - /usr/lib/x86_64-linux-gnu/libze_intel_npu.so.1.32.1:/usr/lib/x86_64-linux-gnu/libze_intel_npu.so.1.32.1:ro - /usr/lib/x86_64-linux-gnu/libze_intel_npu.so.1:/usr/lib/x86_64-linux-gnu/libze_intel_npu.so.1:ro - /usr/lib/x86_64-linux-gnu/libze_intel_npu.so:/usr/lib/x86_64-linux-gnu/libze_intel_npu.so:ro - /usr/lib/x86_64-linux-gnu/libnpu_driver_compiler.so:/usr/lib/x86_64-linux-gnu/libnpu_driver_compiler.so:ro healthcheck: test: [ "CMD-SHELL", "curl -f http://localhost:8080/health >/dev/null 2>&1 || exit 1", ] interval: 30s timeout: 5s start_period: 30s retries: 3 labels: agentmon.monitor: "true" agentmon.role: "voice" agentmon.port: "18816" # Manual fallback whisper.cpp server: CPU-only, medium model. # Kept around for resilience — runs if the NPU/GPU servers are down. Uses no # accelerator resources, but is slow (~14 s per short clip). # Disabled from the normal `voice` profile now that `whisper-server-npu` is # the trial default. Start manually with: # docker compose --profile voice-cpu-backup up -d whisper-server whisper-server: image: ghcr.io/ggml-org/whisper.cpp@sha256:672650b5e67f9cb86af7ac6e09dea8eac12a024086e1e5c0172fdccf336aba09 container_name: whisper-server restart: unless-stopped profiles: ["voice-cpu-backup"] ports: - "18811:8080" volumes: - whisper-models:/app/models # Override image entrypoint so args are passed directly to whisper-server. entrypoint: ["whisper-server"] command: - --model - /app/models/ggml-medium.bin - --host - 0.0.0.0 - --port - "8080" - --convert - --language - auto - --inference-path - /v1/audio/transcriptions depends_on: whisper-init: condition: service_completed_successfully healthcheck: test: [ "CMD-SHELL", "curl -f http://localhost:8080/ >/dev/null 2>&1 || exit 1", ] interval: 30s timeout: 5s start_period: 15s retries: 3 labels: agentmon.monitor: "true" agentmon.role: "voice" agentmon.port: "18811" # kokoro TTS kokoro-tts: image: ghcr.io/remsky/kokoro-fastapi-cpu@sha256:c8812546d358cbfd6a5c4087a28795b2b001d8e32d7a322eedd246e6bc13cb55 container_name: kokoro-tts profiles: ["voice"] ports: - "18805:8880" environment: - USE_GPU=false # - PYTHONUNBUFFERED=1 #deploy: # resources: # reservations: # devices: # - driver: nvidia # count: all # capabilities: [gpu] restart: unless-stopped labels: agentmon.monitor: "true" agentmon.role: "voice" agentmon.port: "18805" # Optional local dependency: Brave Search MCP server (HTTP mode). # Start with: docker compose --profile search up -d brave-search brave-search: image: mcp/brave-search@sha256:aea0b091da7029c35f0ed0964367328af0f2824477d79d2e85e43e7cd5a757d4 container_name: brave-search restart: unless-stopped profiles: ["search"] ports: - "18802:8000" environment: - BRAVE_API_KEY=${BRAVE_API_KEY:?BRAVE_API_KEY is required} - BRAVE_MCP_TRANSPORT=http - BRAVE_MCP_HOST=0.0.0.0 - BRAVE_MCP_PORT=8000 labels: agentmon.monitor: "true" agentmon.role: "mcp" agentmon.port: "18802" # Optional local dependency: SearXNG metasearch instance. # Start with: docker compose --profile search up -d searxng searxng: image: searxng/searxng@sha256:c5e5aedb70ec4b7ff5b1e8f8ea69253dceb85a98b8757360c1b65fe8652d6066 container_name: searxng restart: unless-stopped profiles: ["search"] ports: - "18803:8080" environment: - BASE_URL=http://localhost:18803/ - INSTANCE_NAME=Flynn Local SearXNG volumes: - ./searxng/settings.yml:/etc/searxng/settings.yml:ro labels: agentmon.monitor: "true" agentmon.role: "search" agentmon.port: "18803" # Optional local dependency: liteLLM proxy for unified LLM API. # Start with: docker compose --profile api up -d litellm litellm: image: litellm/litellm:v1.83.7-stable container_name: litellm restart: unless-stopped profiles: ["api"] ports: - "18804:4000" volumes: - ./litellm-config.yaml:/app/config.yaml:ro environment: - LITELLM_PORT=4000 - LITELLM_DROP_PARAMS=true - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-} - OPENAI_API_KEY=${OPENAI_API_KEY:-} - OPENROUTER_API_KEY=${OPENROUTER_API_KEY:-} - GEMINI_API_KEY=${GEMINI_API_KEY:-} - ZAI_API_KEY=${ZAI_API_KEY:-} - DATABASE_URL=postgresql://litellm:litellm_password@litellm-db:5432/litellm - LITELLM_MASTER_KEY=${LITELLM_MASTER_KEY:-sk-1234} - LITELLM_SALT_KEY=${LITELLM_SALT_KEY:-} - STORE_MODEL_IN_DB=True command: [ "--config", "/app/config.yaml", "--port", "4000", ] depends_on: litellm-db: condition: service_healthy healthcheck: test: ["CMD-SHELL", "python3 -c \"import urllib.request; urllib.request.urlopen('http://localhost:4000/health/liveliness')\""] interval: 30s timeout: 5s start_period: 15s retries: 3 labels: agentmon.monitor: "true" agentmon.role: "llm-proxy" agentmon.port: "18804" litellm-init: image: curlimages/curl@sha256:d94d07ba9e7d6de898b6d96c1a072f6f8266c687af78a74f380087a0addf5d17 container_name: litellm-init profiles: ["api"] restart: "no" volumes: - ./litellm-init-credentials.sh:/init.sh:ro - ./litellm-init-models.sh:/litellm-init-models.sh:ro environment: - LITELLM_URL=http://litellm:4000 - LITELLM_MASTER_KEY=${LITELLM_MASTER_KEY:-sk-1234} - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-} - OPENAI_API_KEY=${OPENAI_API_KEY:-} - GEMINI_API_KEY=${GEMINI_API_KEY:-} - ZAI_API_KEY=${ZAI_API_KEY:-} entrypoint: ["sh", "/init.sh"] depends_on: litellm: condition: service_healthy litellm-db: image: postgres:15.17-alpine container_name: litellm-db restart: unless-stopped profiles: ["api"] volumes: - litellm-db-data:/var/lib/postgresql/data environment: - POSTGRES_USER=litellm - POSTGRES_PASSWORD=litellm_password - POSTGRES_DB=litellm healthcheck: test: ["CMD-SHELL", "pg_isready -U litellm"] interval: 10s timeout: 5s start_period: 5s retries: 5 labels: agentmon.monitor: "true" agentmon.role: "db" # Dedicated local n8n instance for agent-oriented workflows. # Start with: docker compose --profile automation up -d n8n-agent n8n-agent: image: docker.n8n.io/n8nio/n8n:2.22.1 container_name: n8n-agent restart: unless-stopped profiles: ["automation"] ports: - "18808:5678" environment: - N8N_HOST=0.0.0.0 - N8N_PORT=5678 - N8N_PROTOCOL=http - N8N_EDITOR_BASE_URL=http://localhost:18808 - WEBHOOK_URL=http://localhost:18808/ - TZ=America/Los_Angeles - GENERIC_TIMEZONE=America/Los_Angeles - N8N_SECURE_COOKIE=false volumes: - n8n-agent-data:/home/node/.n8n healthcheck: test: ["CMD-SHELL", "wget -qO- http://localhost:5678/healthz >/dev/null 2>&1 || exit 1"] interval: 30s timeout: 5s start_period: 30s retries: 5 labels: agentmon.monitor: "true" agentmon.role: "automation" agentmon.port: "18808" volumes: # flynn-data: whisper-models: litellm-db-data: n8n-agent-data: