Skip to main content

Local Development

This guide explains how to run AxonFlow locally for development, testing, and single-tenant deployments.

Prerequisites

DependencyMinimum VersionNotes
Go1.25+Required for building from source
Node.js18+Required for Customer Portal UI development
Docker24+Container runtime
Docker Composev2Compose V2 (the docker compose plugin, not standalone docker-compose)
Git2.30+Source control
Version Check
go version        # go1.25 or higher
node --version # v18.x or higher
docker --version # Docker 24.x or higher
docker compose version # v2.x

Build from Source

If you want to build AxonFlow from source rather than using pre-built Docker images:

# Clone the repository
git clone https://github.com/getaxonflow/axonflow.git
cd axonflow

# Build all Go binaries
go build ./platform/...

# Run tests
go test ./platform/... -cover

# Start the full stack with Docker Compose
docker compose up

The docker compose up command builds images locally if they are not already cached. To force a rebuild after code changes:

docker compose up --build

SELF_HOSTED_MODE

For local development and single-tenant deployments, AxonFlow provides SELF_HOSTED_MODE which bypasses license validation entirely.

When to Use SELF_HOSTED_MODE

ScenarioUse SELF_HOSTED_MODE?
Local developmentYes
Unit testingYes
Integration testingYes
Single-tenant internal deploymentYes
Multi-tenant SaaSNo
Production with external clientsNo

Enabling SELF_HOSTED_MODE

Set the environment variable before starting AxonFlow:

export SELF_HOSTED_MODE=true

Or in your docker-compose.yml:

services:
agent:
environment:
- SELF_HOSTED_MODE=true

What Happens When Enabled

When SELF_HOSTED_MODE=true:

  1. License validation is skipped - No license key required
  2. All requests are allowed - No authentication needed
  3. Full connector access - All MCP connectors available
  4. No tenant isolation - All requests treated as same tenant

Quick Start with Docker Compose

# Clone AxonFlow
git clone https://github.com/getaxonflow/axonflow.git
cd axonflow

# Set API key for LLM features (optional)
export OPENAI_API_KEY=sk-your-key-here

# Start all services (SELF_HOSTED_MODE enabled by default)
docker compose up -d

# Check services are healthy
docker compose ps

# Test the agent health
curl http://localhost:8080/health

# Test the orchestrator health
curl http://localhost:8081/health

# Run the interactive demo
./examples/demo/demo.sh

# Access Grafana dashboards (optional)
open http://localhost:3001

The Docker Compose setup enables SELF_HOSTED_MODE by default, so you don't need to set it manually.

Services Available:

Security Considerations

warning

SELF_HOSTED_MODE should only be used when:

  • Running locally for development
  • Running in a trusted network environment
  • All applications connecting to AxonFlow are trusted

Never use in production multi-tenant environments -- use proper license keys instead.

Running Tests

With SELF_HOSTED_MODE enabled, you can run the full test suite:

# Run all tests
go test ./...

# Run with coverage
go test -cover ./...

# Run specific module
go test ./platform/agent/...

Hot Reload for Development

For faster iteration during Go development, use air to automatically rebuild and restart when source files change:

# Install air
go install github.com/air-verse/air@latest

# Run the agent with hot reload
cd platform/agent
air

Create an .air.toml configuration in the module directory to customize watched paths and build commands. This avoids manually stopping and restarting the service after every code change.

Local Architecture

┌──────────────────────────────────────────────────┐
│ Your Development Machine │
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ docker-compose │ │
│ │ │ │
│ │ ┌────────┐ ┌──────────────┐ ┌────────┐ │ │
│ │ │ Agent │◄►│ Orchestrator │◄►│ MCP │ │ │
│ │ │ :8080 │ │ :8081 │ │ │ │ │
│ │ └────────┘ └──────────────┘ └────────┘ │ │
│ │ │ │ │
│ │ ▼ │ │
│ │ ┌───────────────────┐ │ │
│ │ │ PostgreSQL │ │ │
│ │ │ :5432 │ │ │
│ │ └───────────────────┘ │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ SELF_HOSTED_MODE=true │
│ (No license validation) │
└──────────────────────────────────────────────────┘

Transitioning to Production

When you're ready to move from local development to production:

  1. SaaS Multi-Tenant: Contact [email protected] for service licenses
  2. In-VPC Single-Tenant: Keep SELF_HOSTED_MODE if all apps are trusted, or use licenses for external apps
  3. AWS Marketplace: Follow the AWS Marketplace deployment guide

See the Enterprise License Management documentation for detailed licensing information.

Troubleshooting

"License validation failed" Error

If you see this error during local development:

License validation failed: license key required

Solution: Ensure SELF_HOSTED_MODE=true is set:

export SELF_HOSTED_MODE=true
# Then restart AxonFlow

Container Can't Connect to Database

If the agent can't connect to PostgreSQL:

# Check if PostgreSQL is running
docker compose ps

# View PostgreSQL logs
docker compose logs postgres

# Restart all services
docker compose down && docker compose up

Port Already in Use

If ports 8080, 8081, or 5432 are already in use:

# Find what's using the port
lsof -i :8080

# Kill the process if appropriate
kill -9 <PID>

# Or use different ports in docker-compose.yml
# ports:
# - "9080:8080" # Map to 9080 instead

Docker Out of Memory

If containers crash or become unresponsive, Docker may not have enough memory allocated:

# Check Docker resource usage
docker stats --no-stream

# Check Docker settings — allocate at least 8 GB RAM
# On Docker Desktop: Settings → Resources → Memory → 8.00 GB

AxonFlow's full stack (agent, orchestrator, PostgreSQL, Redis, Grafana, Prometheus) requires approximately 4-6 GB of memory. The default Docker Desktop allocation of 2 GB is insufficient.

Go Module Cache Issues

If go build or go test fails with module resolution errors after switching branches or updating dependencies:

# Clear the module download cache
go clean -modcache

# Re-download dependencies
go mod download

# Verify module graph
go mod verify

Orchestrator Connection Refused

If the agent starts but cannot reach the orchestrator:

# Verify orchestrator is running
curl http://localhost:8081/health

# Check orchestrator logs for startup errors
docker compose logs orchestrator

# Ensure both services are on the same Docker network
docker compose ps

The agent expects the orchestrator at the hostname orchestrator:8081 within the Docker network. If you are running services outside Docker, set ORCHESTRATOR_URL=http://localhost:8081 on the agent.

Contributing

See the Contributing Guide for development workflow, code style, testing requirements, and how to submit pull requests.

Next Steps