mirror of
https://gitee.com/wanwujie/deer-flow
synced 2026-04-03 06:12:14 +08:00
The dev compose file was missing CLI auth directory mounts that exist in the production compose file. This caused CodexChatModel to fail with 'Codex CLI credential not found' error in dev mode. Fixes #1246
216 lines
7.8 KiB
YAML
216 lines
7.8 KiB
YAML
# DeerFlow Development Environment
|
|
# Usage: docker-compose -f docker-compose-dev.yaml up --build
|
|
#
|
|
# Services:
|
|
# - nginx: Reverse proxy (port 2026)
|
|
# - frontend: Frontend Next.js dev server (port 3000)
|
|
# - gateway: Backend Gateway API (port 8001)
|
|
# - langgraph: LangGraph server (port 2024)
|
|
# - provisioner (optional): Sandbox provisioner (creates Pods in host Kubernetes)
|
|
#
|
|
# Prerequisites:
|
|
# - Kubernetes cluster + kubeconfig are only required when using provisioner mode.
|
|
#
|
|
# Access: http://localhost:2026
|
|
|
|
services:
|
|
# ── Sandbox Provisioner ────────────────────────────────────────────────
|
|
# Manages per-sandbox Pod + Service lifecycle in the host Kubernetes
|
|
# cluster via the K8s API.
|
|
# Backend accesses sandboxes directly via host.docker.internal:{NodePort}.
|
|
provisioner:
|
|
profiles:
|
|
- provisioner
|
|
build:
|
|
context: ./provisioner
|
|
dockerfile: Dockerfile
|
|
container_name: deer-flow-provisioner
|
|
volumes:
|
|
- ~/.kube/config:/root/.kube/config:ro
|
|
environment:
|
|
- K8S_NAMESPACE=deer-flow
|
|
- SANDBOX_IMAGE=enterprise-public-cn-beijing.cr.volces.com/vefaas-public/all-in-one-sandbox:latest
|
|
# Host paths for K8s HostPath volumes (must be absolute paths accessible by K8s node)
|
|
# On Docker Desktop/OrbStack, use your actual host paths like /Users/username/...
|
|
# Set these in your shell before running docker-compose:
|
|
# export DEER_FLOW_ROOT=/absolute/path/to/deer-flow
|
|
- SKILLS_HOST_PATH=${DEER_FLOW_ROOT}/skills
|
|
- THREADS_HOST_PATH=${DEER_FLOW_ROOT}/backend/.deer-flow/threads
|
|
- KUBECONFIG_PATH=/root/.kube/config
|
|
- NODE_HOST=host.docker.internal
|
|
# Override K8S API server URL since kubeconfig uses 127.0.0.1
|
|
# which is unreachable from inside the container
|
|
- K8S_API_SERVER=https://host.docker.internal:26443
|
|
env_file:
|
|
- ../.env
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
networks:
|
|
- deer-flow-dev
|
|
restart: unless-stopped
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:8002/health"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 6
|
|
start_period: 15s
|
|
|
|
# ── Reverse Proxy ──────────────────────────────────────────────────────
|
|
# Routes API traffic to gateway/langgraph and (optionally) provisioner.
|
|
# Select nginx config via NGINX_CONF:
|
|
# - nginx.local.conf (default): no provisioner route (local/aio modes)
|
|
# - nginx.conf: includes provisioner route (provisioner mode)
|
|
nginx:
|
|
image: nginx:alpine
|
|
container_name: deer-flow-nginx
|
|
ports:
|
|
- "2026:2026"
|
|
volumes:
|
|
- ./nginx/${NGINX_CONF:-nginx.conf}:/etc/nginx/nginx.conf:ro
|
|
depends_on:
|
|
- frontend
|
|
- gateway
|
|
- langgraph
|
|
networks:
|
|
- deer-flow-dev
|
|
restart: unless-stopped
|
|
|
|
# Frontend - Next.js Development Server
|
|
frontend:
|
|
build:
|
|
context: ../
|
|
dockerfile: frontend/Dockerfile
|
|
target: dev
|
|
args:
|
|
PNPM_STORE_PATH: ${PNPM_STORE_PATH:-/root/.local/share/pnpm/store}
|
|
container_name: deer-flow-frontend
|
|
command: sh -c "cd frontend && pnpm run dev > /app/logs/frontend.log 2>&1"
|
|
volumes:
|
|
- ../frontend/src:/app/frontend/src
|
|
- ../frontend/public:/app/frontend/public
|
|
- ../frontend/next.config.js:/app/frontend/next.config.js:ro
|
|
- ../logs:/app/logs
|
|
# Mount pnpm store for caching
|
|
- ${PNPM_STORE_PATH:-~/.local/share/pnpm/store}:/root/.local/share/pnpm/store
|
|
working_dir: /app
|
|
environment:
|
|
- NODE_ENV=development
|
|
- WATCHPACK_POLLING=true
|
|
- CI=true
|
|
env_file:
|
|
- ../frontend/.env
|
|
networks:
|
|
- deer-flow-dev
|
|
restart: unless-stopped
|
|
|
|
# Backend - Gateway API
|
|
gateway:
|
|
build:
|
|
context: ../
|
|
dockerfile: backend/Dockerfile
|
|
# cache_from disabled - requires manual setup: mkdir -p /tmp/docker-cache-gateway
|
|
container_name: deer-flow-gateway
|
|
command: sh -c "cd backend && PYTHONPATH=. uv run uvicorn app.gateway.app:app --host 0.0.0.0 --port 8001 --reload --reload-include='*.yaml .env' > /app/logs/gateway.log 2>&1"
|
|
volumes:
|
|
- ../backend/:/app/backend/
|
|
# Preserve the .venv built during Docker image build — mounting the full backend/
|
|
# directory above would otherwise shadow it with the (empty) host directory.
|
|
- gateway-venv:/app/backend/.venv
|
|
- ../config.yaml:/app/config.yaml
|
|
- ../extensions_config.json:/app/extensions_config.json
|
|
- ../skills:/app/skills
|
|
- ../logs:/app/logs
|
|
# Mount uv cache for faster dependency installation
|
|
- ~/.cache/uv:/root/.cache/uv
|
|
# DooD: same as gateway — AioSandboxProvider runs inside LangGraph process.
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
# CLI auth directories for auto-auth (Claude Code + Codex CLI)
|
|
- type: bind
|
|
source: ${HOME:?HOME must be set}/.claude
|
|
target: /root/.claude
|
|
read_only: true
|
|
bind:
|
|
create_host_path: true
|
|
- type: bind
|
|
source: ${HOME:?HOME must be set}/.codex
|
|
target: /root/.codex
|
|
read_only: true
|
|
bind:
|
|
create_host_path: true
|
|
working_dir: /app
|
|
environment:
|
|
- CI=true
|
|
- DEER_FLOW_HOST_BASE_DIR=${DEER_FLOW_ROOT}/backend/.deer-flow
|
|
- DEER_FLOW_HOST_SKILLS_PATH=${DEER_FLOW_ROOT}/skills
|
|
- DEER_FLOW_SANDBOX_HOST=host.docker.internal
|
|
env_file:
|
|
- ../.env
|
|
extra_hosts:
|
|
# For Linux: map host.docker.internal to host gateway
|
|
- "host.docker.internal:host-gateway"
|
|
networks:
|
|
- deer-flow-dev
|
|
restart: unless-stopped
|
|
|
|
# Backend - LangGraph Server
|
|
langgraph:
|
|
build:
|
|
context: ../
|
|
dockerfile: backend/Dockerfile
|
|
# cache_from disabled - requires manual setup: mkdir -p /tmp/docker-cache-langgraph
|
|
container_name: deer-flow-langgraph
|
|
command: sh -c "cd backend && uv run langgraph dev --no-browser --allow-blocking --host 0.0.0.0 --port 2024 > /app/logs/langgraph.log 2>&1"
|
|
volumes:
|
|
- ../backend/:/app/backend/
|
|
# Preserve the .venv built during Docker image build — mounting the full backend/
|
|
# directory above would otherwise shadow it with the (empty) host directory.
|
|
- langgraph-venv:/app/backend/.venv
|
|
- ../config.yaml:/app/config.yaml
|
|
- ../extensions_config.json:/app/extensions_config.json
|
|
- ../skills:/app/skills
|
|
- ../logs:/app/logs
|
|
# Mount uv cache for faster dependency installation
|
|
- ~/.cache/uv:/root/.cache/uv
|
|
# DooD: same as gateway — AioSandboxProvider runs inside LangGraph process.
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
# CLI auth directories for auto-auth (Claude Code + Codex CLI)
|
|
- type: bind
|
|
source: ${HOME:?HOME must be set}/.claude
|
|
target: /root/.claude
|
|
read_only: true
|
|
bind:
|
|
create_host_path: true
|
|
- type: bind
|
|
source: ${HOME:?HOME must be set}/.codex
|
|
target: /root/.codex
|
|
read_only: true
|
|
bind:
|
|
create_host_path: true
|
|
working_dir: /app
|
|
environment:
|
|
- CI=true
|
|
- DEER_FLOW_HOST_BASE_DIR=${DEER_FLOW_ROOT}/backend/.deer-flow
|
|
- DEER_FLOW_HOST_SKILLS_PATH=${DEER_FLOW_ROOT}/skills
|
|
- DEER_FLOW_SANDBOX_HOST=host.docker.internal
|
|
env_file:
|
|
- ../.env
|
|
extra_hosts:
|
|
# For Linux: map host.docker.internal to host gateway
|
|
- "host.docker.internal:host-gateway"
|
|
networks:
|
|
- deer-flow-dev
|
|
restart: unless-stopped
|
|
|
|
volumes:
|
|
# Persist .venv across container restarts so dependencies installed during
|
|
# image build are not shadowed by the host backend/ directory mount.
|
|
gateway-venv:
|
|
langgraph-venv:
|
|
|
|
networks:
|
|
deer-flow-dev:
|
|
driver: bridge
|
|
ipam:
|
|
config:
|
|
- subnet: 192.168.200.0/24
|