AgentX docs

Production Deployment

For local development the API runs on your host (via task dev) against Dockerized databases. For production, AgentX runs the API itself in a container using the production Docker Compose profile.

The deployment unit is a cluster — a self-contained instance with its own .env, config, database storage, and ports. Even a single private instance is just a cluster without the public gateway. This page covers the production profile and required configuration; for the full workflow (scaffolding, the optional Nginx + Cloudflare gateway, GPU overlay, running multiple instances) see Clusters.

The production profile

The api service in docker-compose.yml is gated behind profiles: [production], so it only starts when you opt in with --profile production. You never invoke Compose directly — the cluster:* tasks assemble the right --env-file and overlays for you (see the Clusters lifecycle table).

The base docker-compose.yml pulls the published API image (${AGENTX_IMAGE:-qrmadness/agentx-api:latest}). Local clusters layer docker-compose.build.yml on top to build from the repo Dockerfile instead (Python + uv, Node for local MCP tools); the cluster:* tasks add this overlay automatically. The API is served by uvicorn (ASGI) on port 12319, restarts unless-stopped, and self-initializes its schemas on boot via the container entrypoint (so cluster:migrate is belt-and-suspenders, not required).

Services & resource limits

ServiceImageMemory limit / reservation
apibuilt from Dockerfile8G / 4G
neo4jneo4j:5.15-community4G / 2G
postgrespgvector/pgvector:pg162G / 512M
redisredis:7-alpine768M / 256M

Required configuration

Set these in the cluster’s .env (clusters/<name>/.env, scaffolded by cluster:new) before cluster:up:

# Django — REQUIRED, no safe default
DJANGO_SECRET_KEY=<generate a long random key>
DJANGO_DEBUG=false
DJANGO_ALLOWED_HOSTS=your.host.or.ip

# Database credentials — change the defaults
NEO4J_PASSWORD=<strong>
POSTGRES_USER=agent
POSTGRES_PASSWORD=<strong>
POSTGRES_DB=agent_memory

# Host ports (override to avoid conflicts between clusters)
API_PORT=12319
NEO4J_HTTP_PORT=7474
NEO4J_BOLT_PORT=7687
POSTGRES_PORT=5432
REDIS_PORT=6379

cluster:new also writes AGENTX_CONFIG_DIR and AGENTX_DB_DIR (pointing at clusters/<name>/config and clusters/<name>/db) so the container reads config from and persists database data into the cluster directory.

Plus any LLM provider keys (ANTHROPIC_API_KEY, OPENAI_API_KEY, …) and CORS settings you need. See Configuration for the full list.

Bring-up sequence

A private single-host instance (no public gateway):

task cluster:new CLUSTER=prod            # scaffold clusters/prod/ + seed config
# edit clusters/prod/.env: DJANGO_SECRET_KEY, DJANGO_DEBUG=false, passwords, provider keys
task cluster:up CLUSTER=prod             # build + start API + databases
task cluster:migrate CLUSTER=prod        # apply Django + memory schema (vector indexes, etc.)
task cluster:auth:setup CLUSTER=prod     # set the root password (if AGENTX_AUTH_ENABLED=true)
task cluster:warmup CLUSTER=prod         # pre-load the embedding model (avoids a slow first request)
task cluster:status CLUSTER=prod         # confirm everything is healthy

!!! warning “Don’t skip cluster:migratecluster:migrate runs the in-image bootstrap: the Django/PostgreSQL ORM tables, the memory PostgreSQL (Alembic), and the Neo4j/Redis memory schema in one pass (already-current schemas are verified by version stamps in seconds). The memory schema creates the vector indexes recall and the semantic-duplicate check rely on — without it, consolidation logs fact_embeddings index missing and silently stops de-duplicating.

Verify the API:

curl http://localhost:12319/api/health?include_memory=true

Next steps

  • Authentication — turn on login + the version-compatibility checks
  • Clusters — run multiple instances, add the public gateway, enable GPU