Skip to Content

CodeCraft


Deployment Guide

Browser traffic is always nginx → backend-go (REST/SSE + auth). The Python worker only serves POST /internal/runtasks and is not meant to be exposed to browsers.

Local all-in-one development

make dev
ServicePortRole
backend-go18080Go control plane (public API)
worker8001Python RunTask (internal)
Frontend3000Next.js
nginx2026Single entrypoint

Open http://localhost:2026 .

Docker development stack

Containers: frontend, worker, nginx, and optionally provisioner (from config.yaml sandbox mode). backend-go runs on the host (host.docker.internal:18080).

Prerequisites

  • Docker
  • config.yaml at repo root
  • DEER_FLOW_WORKER_SECRET in .env (openssl rand -hex 32). Host backend-go needs the same DB/Redis setup as full local dev (backend-go/README.md).

Start

export DEER_FLOW_ROOT=/absolute/path/to/deer-flow # required for provisioner mode make docker-start # In another terminal: start backend-go from repo (e.g. `make run` under backend-go)

Equivalent: docker compose -p deer-flow-dev -f docker/docker-compose-dev.yaml up --build from docker/ (keep -p and DEER_FLOW_ROOT as needed).

Open http://localhost:2026 . Stop with make docker-stop.

Docker production

Uses docker/docker-compose.yaml at repo root. Recommended:

./scripts/deploy.sh # build + start detached # ./scripts/deploy.sh build # ./scripts/deploy.sh start # ./scripts/deploy.sh down

Or make up / make down. deploy.sh persists BETTER_AUTH_SECRET, DEER_FLOW_WORKER_SECRET, and AUTH_JWT_SECRET under backend/.deer-flow/ when env vars are unset.

Environment variables

Root .env (loaded via env_file in compose). Typical keys:

OPENAI_API_KEY=sk-... DEER_FLOW_ROOT=/absolute/path/to/deer-flow BETTER_AUTH_SECRET=your-secret-min-32-chars BETTER_AUTH_URL=https://your-domain.com AUTH_JWT_SECRET=... # required if not using deploy.sh secret files DEER_FLOW_WORKER_SECRET=...

Always set a strong BETTER_AUTH_SECRET in production. Do not rely on frontend build defaults.

Data persistence

Runtime state lives under DEER_FLOW_HOME (default backend/.deer-flow). Use named volumes or PVCs in production.

Production topics

Sandbox selection

SandboxUse case
LocalSandboxProviderSingle user, trusted host
AioSandboxProvider (Docker)Multi-user, container isolation
AioSandboxProvider + K8s provisionerStrong isolation, multi-user

Kubernetes provisioner

Environment

K8S_NAMESPACE=deer-flow SANDBOX_IMAGE=deerflow-arduino-sandbox:latest # or a registry all-in-one image DEER_FLOW_ROOT=/absolute/path/to/deer-flow

config.yaml

sandbox: use: deerflow.community.aio_sandbox:AioSandboxProvider provisioner_url: http://provisioner:8002

PVCs (optional)

USERDATA_PVC_NAME=deer-flow-userdata-pvc SKILLS_PVC_NAME=deer-flow-skills-pvc

With USERDATA_PVC_NAME, the provisioner uses subPath threads/{thread_id}/user-data per thread.

nginx

Routing is in docker/nginx/nginx.conf: only frontend and backend-go are browser-facing; the worker is not proxied for /api.

Authentication (Better Auth)

  1. BETTER_AUTH_SECRET: strong random, ≥32 chars
  2. BETTER_AUTH_URL: public origin
openssl rand -base64 32

Resource hints

ComponentMinimumRecommended
backend-go1 vCPU, 512 MB2 vCPU, 1 GB
worker (agent)2 vCPU, 4 GB RAM4 vCPU, 8 GB RAM
Frontend0.5 vCPU, 512 MB1 vCPU, 1 GB
Sandbox (per session)1 vCPU, 1 GB2 vCPU, 2 GB

Verification

curl -sf http://localhost:2026/health curl -sf http://localhost:2026/api/models

Local-only: curl -sf http://localhost:8001/health (worker).