Checklist

The go-live pass before a self-hosted instance takes real traffic

Run through this once before the stack is reachable by anyone else. It assumes a working Compose install from Installation. Three things separate a laptop trial from a real deployment:

  • Replace the dev-only secret defaults, and bring the stack up with the production overlay so it refuses to boot until they’re set
  • Switch the backend to production mode
  • Move the compose-managed data stores to managed services

Replace the dev-only secrets

The stack boots with dev-only placeholders baked into docker-compose.yml, values like local-dev-only-not-for-production-replace-me, and futureagi for the database passwords. It runs fine with them, which is the point on a laptop and the danger in production.

What forces real secrets is the production overlay, deploy/docker-compose.production.yml. It re-binds each one with ${VAR:?}, so the stack won’t start until you’ve set them.

These values go in deploy/.env.production, not the root .env. Copy the shipped example and fill it in:

cp deploy/.env.production.example deploy/.env.production

Set, at minimum:

  • SECRET_KEY
  • AGENTCC_INTERNAL_API_KEY
  • AGENTCC_ADMIN_TOKEN
  • PG_PASSWORD
  • MINIO_ROOT_PASSWORD
  • RABBITMQ_USER and RABBITMQ_PASSWORD
  • FRONTEND_URL and VITE_HOST_API
openssl rand -hex 32     # SECRET_KEY, AGENTCC_INTERNAL_API_KEY, AGENTCC_ADMIN_TOKEN
openssl rand -base64 24  # PG_PASSWORD, MINIO_ROOT_PASSWORD, RABBITMQ_PASSWORD

Then bring the stack up with both files:

docker compose --env-file deploy/.env.production \
  -f docker-compose.yml -f deploy/docker-compose.production.yml up -d

Miss one and compose refuses to start, naming the variable it wanted. That’s the overlay doing its job, not a broken install.

Warning

PG_PASSWORD is baked into the Postgres volume on the first boot, so set it before your first docker compose up. MINIO_ROOT_PASSWORD is read from the environment on every boot, so that one you can change and restart. The full field list is in Environment variables.

Switch the backend to production mode

Set these runtime flags before going live:

VariableGo-live valueWhy
ENV_TYPEprodDefaults to development. Disables debug output and runs Django check --deploy
GRANIAN_WORKERSyour CPU countOne worker per core, up from the default 1
FAST_STARTUPleave unsetAlready false. Setting it true skips migrations and DB checks at boot, which you never want here

check --deploy warns and continues rather than refusing to start, so a failing deployment check won’t stop the container. Read the backend logs on your first prod boot instead of assuming a clean start means a clean report.

Move to managed data stores

Compose-managed Postgres, ClickHouse, Redis, and MinIO are fine for a trial. For production, point the stack at managed services. The catch: the backend reads these hosts from hardcoded values in the backend env block of docker-compose.yml (PG_HOST: postgres, CH_HOST: clickhouse, REDIS_URL: redis://redis:6379/0, S3_ENDPOINT_URL: http://minio:9000), not from .env. Setting them in .env does nothing. You edit the compose file.

ReplaceWithEdit in docker-compose.yml
postgresRDS, Aurora, or Cloud SQLPG_HOST / PG_PORT to the managed endpoint
clickhouseClickHouse CloudCH_HOST / CH_PORT and the credentials
redisElastiCache or UpstashREDIS_URL
minioAWS S3STORAGE_BACKEND: s3 and the S3 credentials

Note

code-executor runs with privileged: true, so it can’t run on ECS Fargate or Cloud Run. Put it on an EC2 or GCE instance. The platform matrix is in Requirements.

Dive deeper

Was this page helpful?

Questions & Discussion