services: mitmproxy: build: ./proxy command: - mitmweb - --mode - regular@8080 - --mode - transparent@8085 - --web-host - "0.0.0.0" - --web-port - "8081" - --set - web_password=${MITMPROXY_WEB_PASSWORD:-mitmpass} - --scripts - /home/mitmproxy/scripts/stream_sse.py - --verbose ports: - "${LLM_PROXY_PORT:-4000}:4000" # llm-proxy - "${MITMPROXY_UI_PORT:-8081}:8081" # mitmproxy web UI - "3000:3000" # chat UI (optional: claude-chat profile) - "4100:4100" # sdk-proxy (optional: claude-proxy profile) environment: - PYTHONUNBUFFERED=1 - MITMPROXY_STREAM_SSE=${MITMPROXY_STREAM_SSE:-true} volumes: - mitmproxy-certs:/home/mitmproxy/.mitmproxy - ./proxy:/home/mitmproxy/scripts:ro healthcheck: test: ["CMD", "python3", "-c", "import socket; s=socket.create_connection(('localhost',8081),2); s.close()"] interval: 2s timeout: 5s retries: 15 networks: default: llm-proxy-net: aliases: - llm-proxy - mitmproxy-ui llm-proxy: build: ./llm-proxy network_mode: "service:mitmproxy" depends_on: mitmproxy: condition: service_healthy cap_add: - NET_ADMIN environment: - LLM_PROXY_PORT=4000 - TRACE_EXPORTERS=${TRACE_EXPORTERS:-phoenix} - OPIK_OTEL_ENDPOINT=${OPIK_OTEL_ENDPOINT:-http://opik-frontend:5173/api/v1/private/otel/v1/traces} - OPIK_PROJECT_NAME=${OTEL_PROJECT_NAME:-llm-proxy} - OPIK_API_KEY=${OPIK_API_KEY:-} - OPIK_WORKSPACE=${OPIK_WORKSPACE:-} - OPIK_OTEL_HEADERS=${OPIK_OTEL_HEADERS:-} - PHOENIX_COLLECTOR_ENDPOINT=${PHOENIX_COLLECTOR_ENDPOINT:-http://phoenix:6006} - PHOENIX_PROJECT_NAME=${OTEL_PROJECT_NAME:-llm-proxy} - PHOENIX_API_KEY=${PHOENIX_API_KEY:-} - PHOENIX_OTEL_HEADERS=${PHOENIX_OTEL_HEADERS:-} - KEYS_PATH=/app/keys.jsonc volumes: - ./keys.jsonc:/app/keys.jsonc:ro - mitmproxy-certs:/certs:ro healthcheck: test: ["CMD", "curl", "-sf", "http://localhost:4000/health"] interval: 2s timeout: 5s retries: 15 phoenix: image: arizephoenix/phoenix:latest profiles: ["phoenix"] ports: - "6006:6006" - "4317:4317" environment: - PHOENIX_WORKING_DIR=/mnt/data volumes: - ./data/phoenix:/mnt/data healthcheck: test: ["CMD", "curl", "-sf", "http://localhost:6006"] interval: 5s timeout: 5s retries: 12 networks: default: llm-proxy-net: aliases: - phoenix claude-sdk-chat: build: ./claude/sdk-chat profiles: ["claude-chat"] network_mode: "service:mitmproxy" depends_on: mitmproxy: condition: service_healthy cap_add: - NET_ADMIN environment: - CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-} - MITMPROXY_WEB_PASSWORD=${MITMPROXY_WEB_PASSWORD:-mitmpass} - HTTP_PROXY=http://localhost:8080 - HTTPS_PROXY=http://localhost:8080 - NO_PROXY=localhost,127.0.0.1 volumes: - ./claude/sdk-chat/app:/app - mitmproxy-certs:/certs:ro - ./data/claude/credentials.json:/credentials/.credentials.json:ro claude-code: build: ./claude/claude-code profiles: ["claude-code"] network_mode: "service:mitmproxy" depends_on: mitmproxy: condition: service_healthy cap_add: - NET_ADMIN stdin_open: true tty: true environment: - CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-} - HTTP_PROXY=http://localhost:8080 - HTTPS_PROXY=http://localhost:8080 - NO_PROXY=localhost,127.0.0.1 volumes: - mitmproxy-certs:/certs:ro - claude-code-home:/root claude-sdk-proxy: build: ./claude/sdk-proxy profiles: ["claude-proxy"] network_mode: "service:mitmproxy" depends_on: mitmproxy: condition: service_healthy cap_add: - NET_ADMIN environment: - CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY:-} - API_SERVER_KEY=${CLAUDE_PROXY_API_KEY:-} - API_PORT=4100 - LOG_LEVEL=${CLAUDE_PROXY_LOG_LEVEL:-debug} # Input transformers for modifying prompts - useful for fixing cache control issues - PLUGINS_TRANSFORM=${CLAUDE_PROXY_PLUGINS_TRANSFORM:-} # Route claude proxy through the llm-proxy by default to capture traces - CLAUDE_PROXY_ANTHROPIC_BASE_URL=${CLAUDE_PROXY_ANTHROPIC_BASE_URL:-http://localhost:4000/anthropic} - HTTP_PROXY=http://localhost:8080 - HTTPS_PROXY=http://localhost:8080 - NO_PROXY=localhost,127.0.0.1 volumes: - ./data/claude/sdk-proxy:/data - mitmproxy-certs:/certs:ro - ./data/claude/credentials.json:/credentials/.credentials.json:ro networks: llm-proxy-net: name: ${NETWORK_NAME:-llm-proxy-net} external: true volumes: mitmproxy-certs: claude-code-home: