qaitai docs

Self-host with Docker Compose

The whole stack on one host, free and without limits.

The compose stack runs web (control plane), a runner, Postgres 17, Hatchet (job queue), MinIO (storage) and the open-source Steel browser. Requirements: Docker with Compose v2, about 4 GB of RAM, and openssl.

Get the code and generate secrets

git clone https://github.com/qaitai/qaitai && cd qaitai
sh docker/init-env.sh

docker/init-env.sh writes docker/.env with generated secrets (QAITAI_MASTER_KEY, BETTER_AUTH_SECRET, QAITAI_INTERNAL_SECRET, database and storage passwords) and never overwrites an existing file. Back up QAITAI_MASTER_KEY: without it, stored model keys and test secrets can't be decrypted.

Configure

Edit docker/.env: set QAITAI_URL, a way to sign in, and a model key (ANTHROPIC_API_KEY or AI_GATEWAY_API_KEY). All settings: Environment variables.

Start it

docker compose -f docker/compose.yml up -d

On first start the stack creates the database roles (the app connects as qaitai_app, which can't bypass row-level security), mints a Hatchet worker token, runs migrations and creates the storage bucket.

Sign in as the admin

Open QAITAI_URL (default http://localhost:3000). No email or GitHub App yet? The web container prints a one-time sign-in link while the instance has no users:

docker compose -f docker/compose.yml logs web | grep -A2 "no users yet"

The first account becomes the instance admin. Sign-up is invite-only after that unless you set QAITAI_ALLOW_SIGNUP=true, for every method: GitHub, Google, magic link and email + password.

Email + password needs no extra setup. With SMTP configured, new password accounts confirm their email before signing in and Forgot password? sends a reset link; without mail they sign in unconfirmed and reset isn't available. Existing users can add a password under Settings → Account.

Operating it

  • Only web is published (default 0.0.0.0:3000). Put TLS in front with your reverse proxy and set QAITAI_URL to the public https URL.
  • Health: GET /api/health (liveness) and GET /api/health?db=1 (readiness).
  • Upgrade: set QAITAI_VERSION, then docker compose -f docker/compose.yml pull && docker compose -f docker/compose.yml up -d.
  • More runners: docker compose -f docker/compose.yml up -d --scale runner=3.
  • Backups: docker compose -f docker/compose.yml exec postgres pg_dumpall -U postgres > backup.sql, and keep QAITAI_MASTER_KEY apart from them.
  • Domain verification is off by default on your own instance (QAITAI_REQUIRE_DOMAIN_VERIFICATION=false); turn it on if untrusted people share the instance.

Browsers, email, the GitHub App and more: docs/self-hosting.md.

On this page