services: backend: build: context: . dockerfile: Dockerfile container_name: fennec-backend restart: unless-stopped ports: - "8000:8000" environment: - PYTHONPATH=/app # LLM Configuration - LLM_PROVIDER=${LLM_PROVIDER:-anthropic} - LLM_MODEL=${LLM_MODEL:-claude-sonnet-4-20250514} # Robustness: the OSS default (60s / 2 retries) is too low for the rich # analyst/pentester structured-output calls — they time out and get # silently dropped, producing 0 hypotheses. Production uses 180/4. - FENNEC_LLM_TIMEOUT=${FENNEC_LLM_TIMEOUT:-600} - FENNEC_LLM_MAX_RETRIES=${FENNEC_LLM_MAX_RETRIES:-5} # API Keys - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} - OPENAI_API_KEY=${OPENAI_API_KEY} - OPENROUTER_API_KEY=${OPENROUTER_API_KEY} # Search API Keys (optional) - FENNEC_TAVILY_API_KEY=${TAVILY_API_KEY} - FENNEC_PERPLEXITY_API_KEY=${PERPLEXITY_API_KEY} # Docker Configuration - FENNEC_DOCKER_IMAGE=${DOCKER_IMAGE:-fennec-linux} # Opt-in: set FENNEC_DEMO_SEED=1 to populate the dashboard with # synthetic data on startup (useful for previewing the UI without # running a real scan). - FENNEC_DEMO_SEED=${FENNEC_DEMO_SEED:-} # LangChain / LangSmith tracing (pass-through from host .env) - LANGCHAIN_TRACING_V2=${LANGCHAIN_TRACING_V2:-} - LANGCHAIN_API_KEY=${LANGCHAIN_API_KEY:-} - LANGCHAIN_PROJECT=${LANGCHAIN_PROJECT:-fennec-ai} - LANGCHAIN_ENDPOINT=${LANGCHAIN_ENDPOINT:-https://api.smith.langchain.com} - LANGSMITH_TRACING=${LANGSMITH_TRACING:-} - LANGSMITH_API_KEY=${LANGSMITH_API_KEY:-} - LANGSMITH_PROJECT=${LANGSMITH_PROJECT:-fennec-ai} - LANGSMITH_ENDPOINT=${LANGSMITH_ENDPOINT:-https://api.smith.langchain.com} volumes: # Mount Docker socket for spawning pentest containers - /var/run/docker.sock:/var/run/docker.sock # Resolve host.docker.internal to the host machine. Docker Desktop adds # this automatically, but Linux Docker Engine requires the explicit # extra_hosts entry below. Needed so the agent can target services # running on the host (e.g. http://localhost:8080) from inside its # spawned Kali sibling container. extra_hosts: - "host.docker.internal:host-gateway" networks: - fennec-network healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 start_period: 10s frontend: build: context: ./frontend # The dashboard's bundle bakes VITE_API_BASE_URL at build time. For # `docker compose up` we want it to talk to the sibling backend # container via the host port (http://localhost:8000), not the # production Cloud Run URL the Dockerfile defaults to. args: VITE_API_BASE_URL: http://localhost:8000 dockerfile: Dockerfile container_name: fennec-frontend restart: unless-stopped # Internal port matches the nginx `listen` ($PORT, default 8080 inside # the container — see frontend/Dockerfile). External port 3000. ports: - "3000:8080" depends_on: backend: condition: service_healthy networks: - fennec-network networks: fennec-network: driver: bridge