Server deployment
arcflow-server is the HTTP runtime for workflow execution, registry, admin sites, traces, HITL approve, and external callbacks. This guide covers bare-metal and container deployment beyond Compose specifics.
Prerequisites
| Requirement | Notes |
|---|---|
| Postgres 16+ | Required for POST /v1/runs, admin, registry, sites |
| Qdrant | Required for vector memory and site knowledge ingest |
| LLM provider key | At least one of OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY |
| Embedding provider | Not stub in production when RAG is used |
Minimum environment
| Variable | Required | Purpose |
|---|---|---|
ARCFLOW_SERVER_API_KEY | Yes | Protects /v1/runs, registry, trace routes |
ARCFLOW_ADMIN_API_KEY | Yes for admin | Protects /v1/admin/* |
ARCFLOW_POSTGRESQL_URL | Yes for server runs | Connection pool and persistence |
OPENAI_API_KEY (or peer) | Yes for real LLM | Agent execution |
Generate keys:
Use distinct values for server and admin keys. Minimum practical length is 32 hex characters (256 bits of entropy).
Startup sequence
- Environment validation:
main.rsexits ifARCFLOW_SERVER_API_KEYis unset. - Postgres pool:
AppState::from_envconnects whenARCFLOW_POSTGRESQL_URLis set; pool size fromARCFLOW_PG_MAX_CONNECTIONS(default 10). - Migration: Run
arcflow migrate upbefore first traffic, or rely on server auto-migrate and confirm via/ready. - Listen: Binds
0.0.0.0:ARCFLOW_PORT(default 8080). - Readiness: Load balancers should gate on
GET /readyreturning 200.
Container entrypoint: arcflow-server as user arcflow (uid 1000).
Authentication model
| Route group | Auth |
|---|---|
GET /health, GET /ready | None |
/v1/runs, registry, trace | Authorization: Bearer <ARCFLOW_SERVER_API_KEY> |
/v1/admin/* | Authorization: Bearer <ARCFLOW_ADMIN_API_KEY> |
/v1/debug/* | Localhost + ARCFLOW_DEBUG=true (debug feature build) |
Scoped runtime keys via ARCFLOW_STATIC_RUNTIME_KEYS limit which workflows a key may start. Relay upstream calls use scoped keys derived from site configuration.
Postgres requirement behavior
POST /v1/runs returns 503 when Postgres is unset or the pool is unavailable. Embedded SDK runs on a developer laptop do not require Postgres unless recovery or registry features are enabled.
Size the pool: (server_replicas × ARCFLOW_PG_MAX_CONNECTIONS) < postgres max_connections.
CORS
ARCFLOW_CORS_ORIGINS accepts a comma-separated allowlist for browser-direct server calls. Production static sites should use Relay instead of exposing the server API key in the browser.
Request limits
Admin and runtime routes enforce a 1 MiB request body limit. Large knowledge ingest should chunk text in multiple admin calls if approaching the limit.
Graceful shutdown
The server uses Axum/Tokio serve on the main listener. On SIGTERM (Docker stop, Kubernetes preStop), the process exits when in-flight requests complete per Tokio shutdown semantics. For zero-downtime deploys, drain the load balancer before sending SIGTERM.
Recommended Kubernetes pattern:
Debug endpoints
When built with debug-endpoints feature and ARCFLOW_DEBUG=true, /v1/debug/runs/* routes are merged. Keep ARCFLOW_DEBUG unset or false in production. Debug routes are intended for localhost troubleshooting only.
External callbacks
Set ARCFLOW_WEBHOOK_SECRET before enabling external binding workflows. Without it, external callback handlers reject requests. See Webhook HMAC.
Verification after deploy
Adjust workflow JSON to match a valid minimal definition in your environment.
Load test reference: bash scripts/load-test-runs.sh.
Backup
Back up Postgres (runs, recovery, registry, sites, trace events). Qdrant volumes hold vector data; back up arcflow_qdrant_data or use Qdrant snapshot APIs for RAG-heavy deployments.
Related pages
- Health and readiness
- Migrations runbook (ArcFlow repository)
- Environment variables reference
- API key management
- Production checklist