Self-Hosted Deployment
AxonFlow Community is source-available under BSL 1.1 and runs locally with Docker Compose. This path is ideal for engineers trying the platform, building governed AI applications, and standing up an internal sandbox before moving to higher tiers.
It is also the fastest way to learn the real runtime shape of AxonFlow:
- Agent on
8080 - Orchestrator on
8081 - PostgreSQL and Redis for state and coordination
- Prometheus and Grafana for observability
That matters because a lot of teams first encounter AxonFlow through SDK snippets or policy docs. The self-hosted stack is where those abstractions become a concrete system you can inspect end to end.
What You Get
The default compose stack starts:
- Agent for gateway, proxy, policy, and MCP APIs
- Orchestrator for routing, workflows, and multi-agent execution
- PostgreSQL and Redis
- Prometheus and Grafana
In community mode, client auth checks are skipped for the local developer flow, which makes onboarding fast. That is convenient when trying it, but you should still treat the stack as an internal environment and add proper secrets before any serious shared deployment.
The current local compose path uses DEPLOYMENT_MODE=community. That is the supported local-development model and the right default mental model for community self-hosting.
Prerequisites
- Docker Engine or Docker Desktop
- Docker Compose v2
- 4 GB RAM minimum
- 10 GB free disk
- At least one provider key if you want AxonFlow to route LLM calls itself
Quick Start
git clone https://github.com/getaxonflow/axonflow.git
cd axonflow
cp .env.example .env
# Add one or more provider credentials if needed:
# OPENAI_API_KEY=...
# ANTHROPIC_API_KEY=...
docker compose up -d
docker compose ps
Services and Ports
| Service | Port | Notes |
|---|---|---|
| Agent | 8080 | Main API entry point |
| Orchestrator | 8081 | Workflow, routing, WCP |
| PostgreSQL | 5432 | Local database |
| Redis | 6379 | Cache / coordination |
| Prometheus | 9090 | Native metrics scrape target |
| Grafana | 3000 | admin / grafana_localdev456 |
Verify the Stack
curl -s http://localhost:8080/health | jq .
curl -s http://localhost:8081/health | jq .
curl -s http://localhost:8080/prometheus | head
curl -s http://localhost:9090/-/healthy
curl -s http://localhost:3000/api/health
The agent and orchestrator health endpoints return capability-aware JSON. They do not expose every dependency as a hand-curated component table, so rely on both service health and container health when debugging.
Configuration That Matters First
The local stack already wires the core database and Redis settings. The variables most teams care about first are:
| Variable | Purpose |
|---|---|
OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEY | Enable routed LLM providers |
AZURE_OPENAI_* | Enable Azure OpenAI |
OLLAMA_ENDPOINT, OLLAMA_MODEL | Enable local model routing |
DEFAULT_LLM_PROVIDER | Set the preferred provider |
LLM_ROUTING_STRATEGY, PROVIDER_WEIGHTS | Multi-provider routing behavior |
PII_ACTION, SQLI_ACTION | Global security/detection behavior |
MCP_PII_ACTION, MCP_SQLI_ACTION | MCP-specific overrides |
GATEWAY_PII_ACTION, GATEWAY_SQLI_ACTION | Gateway-specific overrides |
MCP_DYNAMIC_POLICIES_ENABLED | Opt into orchestrator-backed MCP dynamic policies |
AXONFLOW_INTERNAL_SERVICE_SECRET | Recommended shared secret for agent-orchestrator service auth |
AXONFLOW_MAP_MAX_TIMEOUT_SECONDS | MAP (Multi-Agent Planning) plan execution budget on the orchestrator. Default 300s, clamped to 60..1800s. Platform v7.2.0+. |
If you are assessing whether Community is enough for your workload, these settings are where that answer usually starts to emerge. Once teams need broader limits, richer governance workflows, or enterprise identity/compliance features, Evaluation and Enterprise become easier to justify.
MAP plan timeout and your ingress
MAP plans chain multiple LLM calls end-to-end, so a five-step plan can run 60-120s before the orchestrator returns. The plan budget is a three-link chain and the smallest link wins; if any of them is shorter than the plan itself the connection is killed mid-stream and the SDK caller sees HTTP 504 Gateway Time-out. Starting on platform v7.2.0 the two knobs you control on a self-hosted deployment are:
| Layer | Knob | Default | Range |
|---|---|---|---|
| SDK client | mapTimeout (TS), map_timeout (Python), MapTimeout (Go), mapTimeout (Java) | 120s | operator choice |
| Orchestrator | AXONFLOW_MAP_MAX_TIMEOUT_SECONDS env | 300s | 60..1800s (clamped) |
If you front the orchestrator with a reverse proxy, load balancer, or service mesh (NGINX, Traefik, Envoy, an ALB, etc.), its idle / read timeout is the third link in the chain. The rule is: SDK mapTimeout must be less than or equal to the orchestrator cap, which must be less than or equal to the proxy idle timeout. Raise them together, never the SDK alone. The orchestrator logs the effective cap at startup when the env is set non-default, and clamp decisions are logged when input falls outside the 60..1800s range.
The Go / Python / TypeScript / Java SDK quickstarts have matching timeout sections (Go, Python, TypeScript, Java).
MCP Connector Configuration
The default compose stack mounts config/axonflow.yaml, which registers several local PostgreSQL-backed demo connectors. You do not need to invent an ENABLED_CONNECTORS list to get started.
If you want a different config file layout, point the agent at it with AXONFLOW_CONFIG_FILE.
Local LLMs
To use Ollama or another local endpoint:
# Example
export OLLAMA_ENDPOINT=http://host.docker.internal:11434
export OLLAMA_MODEL=llama3.2:latest
docker compose up -d
For provider-specific setup, see LLM Overview.
Hardening Before Shared Use
If this stack is going to be used by more than one developer or promoted beyond a laptop sandbox:
- set
AXONFLOW_INTERNAL_SERVICE_SECRET - persist PostgreSQL and Grafana volumes intentionally
- put the stack behind controlled network access
- centralize logs and metrics
- review Security Best Practices
What Leaves The Environment
This is one of the first questions serious reviewers ask, and it should be answered explicitly.
- the AxonFlow runtime itself is self-hosted in your environment
- audit records, policy context, workflow state, and connector enforcement stay in your deployment boundary
- prompts only leave your environment when you send them to the LLM provider you configured
- SDK telemetry can be disabled completely with
AXONFLOW_TELEMETRY=off(canonical);DO_NOT_TRACK=1is also honored today but is deprecated and scheduled for removal after 2026-05-05 — see Telemetry
If you are assessing AxonFlow in a high-scrutiny environment, use Assessing AxonFlow in Regulated Environments and Telemetry alongside this page.
Troubleshooting
Container fails to start
docker compose logs axonflow-agent
docker compose logs axonflow-orchestrator
Common causes:
- Port conflict: another service on 8080 or 8081
- Missing
.envfile: copy from.env.example - Docker memory: allocate at least 4GB to Docker Desktop
Health check returns unhealthy
curl -s http://localhost:8080/health | jq .
If "orchestrator": "unreachable":
- Check orchestrator container is running:
docker compose ps - Check network:
docker compose exec axonflow-agent curl http://axonflow-orchestrator:8081/health - Review orchestrator logs for startup errors
If "database": "disconnected":
- Check postgres container:
docker compose ps postgres - Verify the database exists:
docker compose exec postgres psql -U axonflow -d axonflow -c '\l'
Authentication errors (401)
For community mode without AXONFLOW_INTERNAL_SERVICE_SECRET:
- Requests don't require auth by default
- If you set
AXONFLOW_INTERNAL_SERVICE_SECRET, all requests need Basic auth
Cleanup
docker compose down # Stop containers
docker compose down -v # Stop + remove volumes (resets database)
First Checks That Usually Save Time
When something feels "mostly up, but not actually usable," start with:
- missing provider key: stack is healthy, but routed LLM features are limited
- broken Docker networking: agent and orchestrator are up, but cross-service calls fail
- wrong local model endpoint: Ollama or another local provider is configured but unreachable from containers
- no observability signal: health works, but
/prometheusor Grafana is empty because no traffic has flowed yet
