Docker Compose
Run the control plane, MongoDB and Redis with Docker Compose, then switch on the production overrides for automatic HTTPS — or run it on Node.js directly.
Self-hosted
Start
git clone https://github.com/ankulalwani/agent-orchestration.git && cd agent-orchestration
cp .env.example .env
# set JWT_SECRET and ENCRYPTION_KEY (see the comments in .env.example)
docker compose up -d --build
# open http://localhost:4000 and create the first account (it becomes the platform administrator)Generate the secrets with:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"| Service | What |
|---|---|
control-plane | API and dashboard on port 4000 |
mongo | MongoDB 7 (volume mongo-data) |
redis | Redis 7 with AOF persistence (volume redis-data) |
minio | Only with --profile storage: S3-compatible artifact storage |
Task screenshots and logs go to the artifacts volume unless S3 is configured. One-off commands run in the
container, for example:
docker compose exec control-plane node apps/api/dist/main.js reencrypt-secretsVerified
Run with Docker Desktop (Engine 29.8, WSL 2) on Windows 11: the image builds, the stack starts healthy, the dashboard is served, and a worker on the host paired and completed a task. Data survives recreating the containers. Not yet run on a Linux Docker host.
Production
DOMAIN=orchestration.example.com docker compose -f docker-compose.yml -f docker-compose.production.yml up -d --buildThis adds Caddy with automatic HTTPS, stops exposing port 4000 directly, trusts the proxy and sets resource
limits. ports: !reset [] needs Docker Compose 2.24 or newer. See SSL.
After the first account exists, set ALLOW_REGISTRATION=false and add members from Settings → Members.
People without an account get a single-use invitation link that works even with registration closed.
Demo data
To look around a new, empty installation:
docker compose exec -e SEED_ADMIN_EMAIL=admin@example.com -e SEED_ADMIN_PASSWORD='a-long-password' \
control-plane node apps/api/dist/main.js seed-demoThis creates an administrator, a demo organization, an example project and an example skill. It refuses to run on a database that already has users.
Without Docker
npm install -g pnpm
pnpm install --frozen-lockfile
pnpm --filter @ao/web build
pnpm --filter @ao/api build
pnpm --config.node-linker=hoisted --filter @ao/api deploy --prod /opt/agent-orchestration/api
cp -r apps/web/dist /opt/agent-orchestration/web
cd /opt/agent-orchestration/api
MONGODB_URI=mongodb://127.0.0.1:27017/agent_orchestration \
JWT_SECRET=… ENCRYPTION_KEY=… \
WEB_DIST_DIR=/opt/agent-orchestration/web PUBLIC_URL=https://orchestration.example.com WEB_URL=https://orchestration.example.com \
node dist/main.jsRun the process under your service manager (systemd, etc.) behind a TLS reverse proxy that forwards WebSockets. These steps were run on Windows 11 against MongoDB 8.3.