DeerFlow
Deploying DeerFlow: loopback first, explicit state and one worker
Read the production Compose topology, credential mounts and worker-local execution limits before exposing a DeerFlow instance.
What you will learn
- What make up is expected to start
- Separate immutable configuration from mutable runtime data
- Scale only after identifying who owns the run
Before you start
- Basic Python, HTTP and container concepts
- An owned task with explicit acceptance criteria
Explain the chapter’s implementation boundary and apply its checklist or isolated helper exercise.
Key takeaways
- Host loopback and container listening addresses are different.
- Back up writable runtime state as well as source.
- One worker is the documented production baseline.
What make up is expected to start
The repository documents make up for production images and services. The checked Compose file defines nginx, the Next.js frontend, a FastAPI Gateway and Redis, with an optional provisioner. The Gateway runs uvicorn on its container network and defaults to one worker. This is a multi-service application, not a static frontend that can execute agents by itself.
The nginx host mapping defaults to 127.0.0.1 on port 2026. Container-internal listeners on 0.0.0.0 are distinct from public host exposure. Keep the default during first-run setup. Only expose a reviewed deployment behind your TLS and authentication boundary; changing BIND_HOST is a security decision, not a routine fix for a page that is unreachable from another machine.
Separate immutable configuration from mutable runtime data
Compose mounts config.yaml read-only, but extensions_config.json is writable because Gateway APIs can update MCP and skill-related configuration. It also mounts a persistent DeerFlow home and read-only skills. A backup must account for this difference: retaining source code alone cannot restore the instance’s runtime state or changes made through the application.
The frontend receives BETTER_AUTH_SECRET, and the Gateway has a separate internal authentication token. The base composition does not mount the host Docker socket or personal CLI authentication directories. Those capabilities require explicit overlays. Review sandbox image references, credentials, mounts and network reachability before using an overlay; a container label is not a complete isolation assessment.
Scale only after identifying who owns the run
Redis is used for the stream bridge, but the Gateway command comment states that active run management remains in worker memory. The README describes additional Postgres, lease-heartbeat and durable-event requirements for multi-worker operation, plus remaining coordination limitations. Raising GATEWAY_WORKERS alone does not establish reliable cancellation, deduplication or recovery.
Verify readiness, authenticated access, a bounded test run, artifact retrieval and restart behavior separately. Pin deployed source and image digests and retain a restore procedure before upgrades. The checklist below is not a drop-in Compose replacement and has not been executed against a real instance; it records the safe baseline and the unverified deployment status.
Implementation steps
- 1
Review make setup output and all required secrets without logging their values.
- 2
Inspect Compose with the intended paths and retain loopback binding.
- 3
Use make up only in the prepared evaluation environment.
- 4
Test authentication, artifact retrieval and restoration before public exposure.
Copy-ready example
{"BIND_HOST":"127.0.0.1","PORT":2026,"GATEWAY_WORKERS":1,"dockerSocketMounted":false,"personalCliDirectoriesMounted":false,"runtimeVerified":false}Frequently asked questions
Does adding Redis make every run operation multi-worker safe?
No. Stream delivery and execution ownership are separate; the inspected configuration documents worker-local limitations and additional coordination requirements.
Is the extensions configuration read-only?
Not in the checked production composition. The Gateway can update it, so include it in state-management and backup planning.
Sources
- README.mdSource checked 2026-09-08
- LICENSESource checked 2026-09-08
- backend/README.mdSource checked 2026-09-08
- backend/pyproject.tomlSource checked 2026-09-08
- backend/docs/middleware-execution-flow.mdSource checked 2026-09-08
- backend/packages/harness/deerflow/agents/lead_agent/agent.pySource checked 2026-09-08
- backend/packages/harness/deerflow/agents/middlewares/loop_detection_middleware.pySource checked 2026-09-08
- backend/packages/harness/deerflow/agents/middlewares/_bounded_dict.pySource checked 2026-09-08
- backend/packages/harness/deerflow/config/loop_detection_config.pySource checked 2026-09-08
- backend/packages/harness/deerflow/sandbox/local/local_sandbox_provider.pySource checked 2026-09-08
- backend/app/gateway/auth_middleware.pySource checked 2026-09-08
- backend/app/gateway/csrf_middleware.pySource checked 2026-09-08
- docker/docker-compose.yamlSource checked 2026-09-08