Skip to main content
awaithumans is designed to be self-hostable in one command. The reference Docker Compose file boots:
  • The awaithumans server (with bundled dashboard)
  • Postgres for task storage
  • Health-check endpoints
Once up, point your DNS at the host. Done.

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:
Add .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.
Paste each into .env. Both PAYLOAD_KEY and ADMIN_API_TOKEN must NEVER be regenerated after first deploy:
  • Rotating PAYLOAD_KEY invalidates every session cookie + magic-link token + encrypted Slack OAuth row.
  • Rotating ADMIN_API_TOKEN breaks every running agent until you redeploy them with the new value.
If you must rotate, do it during a planned maintenance window with a coordinated redeploy.

First-run setup

On first boot the server detects an empty users table and prints a one-shot setup URL to the logs:
Open it within an hour, create your operator account. After that, the URL is dead — subsequent setups require an admin to add users via the dashboard. For automation: hit 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 Secure flagged when PUBLIC_URL is HTTPS
  • Magic-link tokens go in URLs that mail clients log
The recommended pattern is a reverse proxy (Caddy / nginx / traefik) terminating TLS in front of the awaithumans container. Caddy example:

Backups

Two things matter:
  1. Postgres data volume (awaithumans-data) — daily snapshot is enough; an hour of lost task data is acceptable for most teams.
  2. PAYLOAD_KEY — without it, encrypted Slack OAuth rows can’t be decrypted. Store it alongside your other root secrets (1Password, Vault, AWS Secrets Manager).
The dashboard build is bundled into the server image; nothing to back up there.

Scaling

The single-process design works up to ~10k tasks per hour without tuning. Beyond that:
  • Run multiple server replicas behind a load balancer
  • Use PgBouncer if 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)
Multi-replica deployments are a documented post-launch hardening pass. For v0.1, single replica is the supported config.

Health check

Wire it to your orchestrator. The endpoint is unauthenticated (it has to be, for healthchecks).

Logs

Structured JSON to stdout. Each log line carries:
  • timestamp (ISO8601)
  • level
  • logger (e.g. awaithumans.server.routes.tasks)
  • message
  • request_id (correlated across the lifetime of one HTTP request)
Pipe to your aggregator of choice. The root logger has a built-in scrubber that redacts API keys, bearer tokens, password fields, and admin-token headers — even if upstream code accidentally logs them. See Configuration.