This guide covers
docker-compose.yaml.
Prerequisites
- Docker Engine 20.10 or later with Compose v2 (
docker compose, notdocker-compose) - A clone of the repository — the Compose file bind-mounts
./config/auth/kratosand./agentarea-platform/temporal-config, so it does not run standalone - Ports 3000, 4433, 7999, 8000 free on the host, plus 5432, 6379, and 9000 if you publish them
- See requirements for the full list
Steps
Create the environment file
.env.example leaves every signing key empty. gen-dev-secrets.sh writes a
fresh value into .env for each key the Compose file requires with no
default: the Kratos signing key, the Ory secrets, the sandbox and MCP gateway
HMAC keys, and the OpenFGA preshared key. It keeps values you already set,
except a sandbox or MCP gateway key that still holds a value an older
.env.example shipped. Those values are public, and the services refuse to
start on them.Generate the secrets that must not stay at their defaults
AGENTAREA_SECRET_ENCRYPTION_KEY is the Fernet key that encrypts every stored
credential — LLM provider keys, MCP server secrets — in the agentarea
database. It must be a valid Fernet key, and it must not change after data
exists, or the ciphertext already written becomes unreadable..env, together with real database and object-store credentials:Start the stack
make up — which runs the same file in the foreground.Compose brings services up in dependency order:dbbecomes healthy (pg_isready), andrustfsbecomes healthy.postgres_initcreates theagentarea,temporal, andkratosdatabases. It is idempotent.app_migrationsrunsagentarea-api migratewith working directory/app/apps/api, andkratos-migrateruns the Kratos schema migration.bucket-initcreates the two object-storage buckets and gives them the CORS allowlist browsers need for direct uploads (AGENTAREA_S3_CORS_ORIGINS, defaulthttp://localhost:3000).app,frontend,agentarea-worker,agentarea-events,agentarea-mcp-manager,sandbox-executor,temporal, andkratosstart.
postgres_init, app_migrations, kratos-migrate,
bucket-init) exit 0 and stay in Exited state. That is the expected result,
not a failure.temporal has a 120-second start_period on its health check, and
agentarea-worker waits for it. First start therefore takes a couple of minutes
before tasks can run.Reach the platform
Compose exposes Kratos directly and does not install a reverse proxy. Before
exposing the host, place Kratos behind an operator-managed proxy and rate-limit
/self-service/* by client IP.The Compose file publishes no ports for PostgreSQL, Valkey, RustFS, Temporal, or
the event service. They are reachable only on the Compose networks.Verify
Check that the long-running services are up and the one-shot jobs completed:Exited (0). Any other exit code means
that step failed and the services depending on it did not start.
Check the two HTTP health endpoints:
Migrations completed successfully. Stamped database to head revision is also a success — it means the schema already existed and Alembic
recorded the current head without replaying migrations.
Troubleshooting
docker compose exits immediately with AGENTAREA_SANDBOX_ACTIVATION_SECRET must be set
docker compose exits immediately with AGENTAREA_SANDBOX_ACTIVATION_SECRET must be set
The Compose file uses
${VAR:?message} for the sandbox and MCP gateway
secrets, so an empty value aborts the run rather than starting an
unauthenticated sandbox path. Run ./scripts/gen-dev-secrets.sh to fill them.mcp-manager or the API exits with is set to a value published in the AgentArea repository
mcp-manager or the API exits with is set to a value published in the AgentArea repository
A sandbox or MCP gateway key still holds a value an older
.env.example or
docker-compose.dev.yaml shipped. Anyone can sign tokens with it. Run
./scripts/gen-dev-secrets.sh, which replaces it, then restart the stack so
every service picks up the new value.The API container restarts in a loop with AGENTAREA_SECRET_ENCRYPTION_KEY environment variable must be set
The API container restarts in a loop with AGENTAREA_SECRET_ENCRYPTION_KEY environment variable must be set
The default secret backend is
database , which requires a Fernet key.
SecretManagerFactory validates this at construction time and raises, so
the process exits at startup instead of failing later on the first secret
read. Generate a key as in step 2.app never starts and app_migrations shows Exited (1)
app never starts and app_migrations shows Exited (1)
Read
docker compose -f docker-compose.yaml logs app_migrations . The
migration command prints Migration failed: followed by the cause. A dirty
database — one with tables from another product but no provider_specs
table — makes Alembic apply migrations onto a schema it does not own. See
[database and migrations](/self-host/database-and- migrations) .The db container refuses to start after an upgrade from an older checkout
The db container refuses to start after an upgrade from an older checkout
postgres:18 stores data under /var/lib/postgresql/<version>/docker , so
the Compose file mounts ./data/postgres at /var/lib/postgresql , not at
the legacy /var/lib/postgresql/data . A data directory laid out for the
old mount point will not start under this file.Tasks stay queued and never execute
Tasks stay queued and never execute
agentarea-worker waits for temporal to pass its health check, which has
a 120-second start period. Check
docker compose -f docker- compose.yaml logs temporal and confirm the
worker is running.Stopping the stack loses data
Stopping the stack loses data
docker compose down -v removes volumes. The platform’s data lives in bind
mounts under ./data/ (postgres, rustfs , valkey ), so down -v does
not remove it — but rm -rf ./data does. See
backup and recovery .Related
Requirements
Host, cluster, and dependency versions required to run AgentArea, per
deployment target
Configuration
Every environment variable each AgentArea service reads, and the Helm value
that sets it
Deploy on Kubernetes with Helm
Install the agentarea Helm chart, decide which bundled dependencies to keep
Choose a secrets backend
Configure where AgentArea stores workspace secrets
Troubleshoot a self-hosted deployment
Diagnose a deployment that will not start