mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-04-25 11:18:22 +00:00
The gateway service was missing these two environment variables that tell it where to find the config files inside the container. Without them, the gateway reads DEER_FLOW_CONFIG_PATH from the host's .env file (set to a host filesystem path), which is not accessible inside the container, causing FileNotFoundError on startup. The langgraph service already had these variables set correctly.
198 lines
7.8 KiB
YAML
198 lines
7.8 KiB
YAML
# DeerFlow Production Environment
|
|
# Usage: make up
|
|
#
|
|
# Services:
|
|
# - nginx: Reverse proxy (port 2026, configurable via PORT env var)
|
|
# - frontend: Next.js production server
|
|
# - gateway: FastAPI Gateway API
|
|
# - langgraph: LangGraph production server (Dockerfile generated by langgraph dockerfile)
|
|
# - provisioner: (optional) Sandbox provisioner for Kubernetes mode
|
|
#
|
|
# Key environment variables (set via environment/.env or scripts/deploy.sh):
|
|
# DEER_FLOW_HOME — runtime data dir, default $REPO_ROOT/backend/.deer-flow
|
|
# DEER_FLOW_CONFIG_PATH — path to config.yaml
|
|
# DEER_FLOW_EXTENSIONS_CONFIG_PATH — path to extensions_config.json
|
|
# DEER_FLOW_DOCKER_SOCKET — Docker socket path, default /var/run/docker.sock
|
|
# DEER_FLOW_REPO_ROOT — repo root (used for skills host path in DooD)
|
|
# BETTER_AUTH_SECRET — required for frontend auth/session security
|
|
#
|
|
# LangSmith tracing is disabled by default (LANGSMITH_TRACING=false).
|
|
# Set LANGSMITH_TRACING=true and LANGSMITH_API_KEY in .env to enable it.
|
|
#
|
|
# Access: http://localhost:${PORT:-2026}
|
|
|
|
services:
|
|
# ── Reverse Proxy ──────────────────────────────────────────────────────────
|
|
nginx:
|
|
image: nginx:alpine
|
|
container_name: deer-flow-nginx
|
|
ports:
|
|
- "${PORT:-2026}:2026"
|
|
volumes:
|
|
- ./nginx/${NGINX_CONF:-nginx.conf}:/etc/nginx/nginx.conf:ro
|
|
depends_on:
|
|
- frontend
|
|
- gateway
|
|
- langgraph
|
|
networks:
|
|
- deer-flow
|
|
restart: unless-stopped
|
|
|
|
# ── Frontend: Next.js Production ───────────────────────────────────────────
|
|
frontend:
|
|
build:
|
|
context: ../
|
|
dockerfile: frontend/Dockerfile
|
|
target: prod
|
|
args:
|
|
PNPM_STORE_PATH: ${PNPM_STORE_PATH:-/root/.local/share/pnpm/store}
|
|
NPM_REGISTRY: ${NPM_REGISTRY:-}
|
|
container_name: deer-flow-frontend
|
|
environment:
|
|
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
|
|
- DEER_FLOW_INTERNAL_GATEWAY_BASE_URL=http://gateway:8001
|
|
- DEER_FLOW_INTERNAL_LANGGRAPH_BASE_URL=http://langgraph:2024
|
|
env_file:
|
|
- ../frontend/.env
|
|
networks:
|
|
- deer-flow
|
|
restart: unless-stopped
|
|
|
|
# ── Gateway API ────────────────────────────────────────────────────────────
|
|
gateway:
|
|
build:
|
|
context: ../
|
|
dockerfile: backend/Dockerfile
|
|
args:
|
|
APT_MIRROR: ${APT_MIRROR:-}
|
|
UV_IMAGE: ${UV_IMAGE:-ghcr.io/astral-sh/uv:0.7.20}
|
|
UV_INDEX_URL: ${UV_INDEX_URL:-https://pypi.org/simple}
|
|
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 --workers 2"
|
|
volumes:
|
|
- ${DEER_FLOW_CONFIG_PATH}:/app/backend/config.yaml:ro
|
|
- ${DEER_FLOW_EXTENSIONS_CONFIG_PATH}:/app/backend/extensions_config.json:ro
|
|
- ../skills:/app/skills:ro
|
|
- ${DEER_FLOW_HOME}:/app/backend/.deer-flow
|
|
# DooD: AioSandboxProvider starts sandbox containers via host Docker daemon
|
|
- ${DEER_FLOW_DOCKER_SOCKET}:/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_HOME=/app/backend/.deer-flow
|
|
- DEER_FLOW_CONFIG_PATH=/app/backend/config.yaml
|
|
- DEER_FLOW_EXTENSIONS_CONFIG_PATH=/app/backend/extensions_config.json
|
|
- DEER_FLOW_CHANNELS_LANGGRAPH_URL=${DEER_FLOW_CHANNELS_LANGGRAPH_URL:-http://langgraph:2024}
|
|
- DEER_FLOW_CHANNELS_GATEWAY_URL=${DEER_FLOW_CHANNELS_GATEWAY_URL:-http://gateway:8001}
|
|
# DooD path/network translation
|
|
- DEER_FLOW_HOST_BASE_DIR=${DEER_FLOW_HOME}
|
|
- DEER_FLOW_HOST_SKILLS_PATH=${DEER_FLOW_REPO_ROOT}/skills
|
|
- DEER_FLOW_SANDBOX_HOST=host.docker.internal
|
|
env_file:
|
|
- ../.env
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
networks:
|
|
- deer-flow
|
|
restart: unless-stopped
|
|
|
|
# ── LangGraph Server ───────────────────────────────────────────────────────
|
|
# TODO: switch to langchain/langgraph-api (licensed) once a license key is available.
|
|
# For now, use `langgraph dev` (no license required) with the standard backend image.
|
|
langgraph:
|
|
build:
|
|
context: ../
|
|
dockerfile: backend/Dockerfile
|
|
args:
|
|
APT_MIRROR: ${APT_MIRROR:-}
|
|
UV_IMAGE: ${UV_IMAGE:-ghcr.io/astral-sh/uv:0.7.20}
|
|
UV_INDEX_URL: ${UV_INDEX_URL:-https://pypi.org/simple}
|
|
container_name: deer-flow-langgraph
|
|
command: sh -c "cd /app/backend && uv run langgraph dev --no-browser --allow-blocking --no-reload --host 0.0.0.0 --port 2024 --n-jobs-per-worker 10"
|
|
volumes:
|
|
- ${DEER_FLOW_CONFIG_PATH}:/app/backend/config.yaml:ro
|
|
- ${DEER_FLOW_EXTENSIONS_CONFIG_PATH}:/app/backend/extensions_config.json:ro
|
|
- ${DEER_FLOW_HOME}:/app/backend/.deer-flow
|
|
- ../skills:/app/skills:ro
|
|
- ../backend/.langgraph_api:/app/backend/.langgraph_api
|
|
# DooD: same as gateway
|
|
- ${DEER_FLOW_DOCKER_SOCKET}:/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
|
|
environment:
|
|
- CI=true
|
|
- DEER_FLOW_HOME=/app/backend/.deer-flow
|
|
- DEER_FLOW_CONFIG_PATH=/app/backend/config.yaml
|
|
- DEER_FLOW_EXTENSIONS_CONFIG_PATH=/app/backend/extensions_config.json
|
|
- DEER_FLOW_HOST_BASE_DIR=${DEER_FLOW_HOME}
|
|
- DEER_FLOW_HOST_SKILLS_PATH=${DEER_FLOW_REPO_ROOT}/skills
|
|
- DEER_FLOW_SANDBOX_HOST=host.docker.internal
|
|
# LangSmith tracing: set LANGSMITH_TRACING=true and LANGSMITH_API_KEY in .env to enable.
|
|
env_file:
|
|
- ../.env
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
networks:
|
|
- deer-flow
|
|
restart: unless-stopped
|
|
|
|
# ── Sandbox Provisioner (optional, Kubernetes mode) ────────────────────────
|
|
provisioner:
|
|
profiles:
|
|
- provisioner
|
|
build:
|
|
context: ./provisioner
|
|
dockerfile: Dockerfile
|
|
args:
|
|
APT_MIRROR: ${APT_MIRROR:-}
|
|
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
|
|
- SKILLS_HOST_PATH=${DEER_FLOW_REPO_ROOT}/skills
|
|
- THREADS_HOST_PATH=${DEER_FLOW_HOME}/threads
|
|
- KUBECONFIG_PATH=/root/.kube/config
|
|
- NODE_HOST=host.docker.internal
|
|
- K8S_API_SERVER=https://host.docker.internal:26443
|
|
env_file:
|
|
- ../.env
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
networks:
|
|
- deer-flow
|
|
restart: unless-stopped
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:8002/health"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 6
|
|
networks:
|
|
deer-flow:
|
|
driver: bridge
|