- The awaithumans server (with bundled dashboard)
- Postgres for task storage
- Health-check endpoints
Entrypoint: awaithumans serve
The published image runs awaithumans serve as its CMD. That’s the production entrypoint — it runs uvicorn against the FastAPI app factory and refuses to start unless AWAITHUMANS_DATABASE_URL (or, for SQLite-on-volume deployments, AWAITHUMANS_DB_PATH) is set explicitly. The compose example below satisfies that by setting AWAITHUMANS_DATABASE_URL to the bundled Postgres service.
For local development against the source tree, use awaithumans dev instead — it auto-generates a PAYLOAD_KEY, an admin token, and a SQLite path under ./.awaithumans/, and writes a discovery file so the SDK auto-connects. Don’t use dev for any deployment you care about — the auto-provisioned SQLite path is not durable across container restarts on most runtimes.
docker-compose.yml
.env file
Compose interpolates${VAR} from a .env file next to docker-compose.yml. Drop this template in beside it and fill in each value before you docker compose up:
.env to .gitignore. Production deployments should pull these from your secrets manager (Vault, AWS Secrets Manager, GCP Secret Manager) rather than a flat file.
Generate the secrets
PAYLOAD_KEY (the encryption root), ADMIN_API_TOKEN (the bearer token your agent uses), and POSTGRES_PASSWORD are the three secrets you set yourself.
.env. Both PAYLOAD_KEY and ADMIN_API_TOKEN must NEVER be regenerated after first deploy:
- Rotating
PAYLOAD_KEYinvalidates every session cookie + magic-link token + encrypted Slack OAuth row. - Rotating
ADMIN_API_TOKENbreaks every running agent until you redeploy them with the new value.
First-run setup
On first boot the server detects an empty users table and prints a one-shot setup URL to the logs:POST /api/setup/operator with the token + operator credentials in JSON. See /api/overview.
TLS / HTTPS
Production REQUIRES HTTPS (AWAITHUMANS_PUBLIC_URL starting with https://):
- Slack OAuth tokens transit via redirect URLs
- Session cookies are
Secureflagged whenPUBLIC_URLis HTTPS - Magic-link tokens go in URLs that mail clients log
Backups
Two things matter:- Postgres data volume (
awaithumans-data) — daily snapshot is enough; an hour of lost task data is acceptable for most teams. - PAYLOAD_KEY — without it, encrypted Slack OAuth rows can’t be decrypted. Store it alongside your other root secrets (1Password, Vault, AWS Secrets Manager).
Scaling
The single-process design works up to ~10k tasks per hour without tuning. Beyond that:- Run multiple
serverreplicas behind a load balancer - Use
PgBouncerif you hit Postgres connection limits - Move the timeout scheduler to a single-leader pattern (currently it runs in every replica — fine at low scale, wasteful at high)
Health check
Logs
Structured JSON to stdout. Each log line carries:timestamp(ISO8601)levellogger(e.g.awaithumans.server.routes.tasks)messagerequest_id(correlated across the lifetime of one HTTP request)