Self-host quickstart (docker compose)#

See also: Self-hosting the control plane — production deployment patterns (Kubernetes, multi-region, TLS, hardening, ops). This page is the local-eval path; that page is the production guide. Both are linked from the main quickstart.

One command. CP + console + state, all on your machine. No image building, no cloning, no Python toolchain. Pulls private images from GHCR — you authenticate with your GitHub PAT.

Prerequisites#

  • Docker Desktop or docker-ce + the Compose plugin (most installs include it).
  • A GitHub PAT with read:packages scope, authorized for the airlockai org if you're behind SSO. Get one at https://github.com/settings/tokens.
  • ~5 GB free disk for images plus the persistent volume.

Install#

# 1. Authenticate to GHCR
echo $GITHUB_TOKEN | docker login ghcr.io -u <your-github-username> --password-stdin

# 2. Run the installer
curl -fsSL https://airlocklabs.ai/install.sh | bash

What it does (paraphrasing install.sh):

  • Generates a fresh operator token.
  • Writes a .env to ~/.airlock/.env.
  • Runs docker compose up -d against the bundled compose.yaml.
  • Polls /health until CP is up.
  • Prints the console URL plus the operator token.

You should see:

Console: http://localhost:3000/login
CP:      http://localhost:8080
Token:   <64 hex chars>

Open the console URL, paste the token, you're in.

What's running#

Three services in one compose stack:

  • cp — control plane on :8080 (HTTP). Persistent volume airlock_state holds state.yaml, the audit log, and the CP's Ed25519 keypair (auto-generated on first boot).
  • console — operator dashboard on :3000 (HTTP). Talks to cp over the docker network.
  • state volume — persistent across restarts.

The worker is not in this stack. The worker runs in your VPC, near your Postgres. Once CP is up, follow Step 3 of the quickstart to mint an enrollment token and install the worker on whatever host has database access.

Customization#

The most-asked overrides:

Pin image versions#

AIRLOCK_CP_IMAGE_TAG=v0.1.0 ./install.sh

Use our hosted console#

Drop the console service from ~/.airlock/compose.yaml and visit https://console.airlocklabs.ai?cp=http://your-cp.example.com.

Production with HTTPS#

Stick Caddy or Cloudflare in front of cp (port 8080); set AIRLOCK_CP_PUBLIC_URL to the public HTTPS URL; restart the stack.

# Add to compose.yaml under cp.environment:
AIRLOCK_CP_PUBLIC_URL: https://cp.example.com

Override the operator token#

Edit ~/.airlock/.env and set a known value, then cd ~/.airlock && docker compose up -d to apply.

Operations#

  • Stop: cd ~/.airlock && docker compose down
  • Restart: cd ~/.airlock && docker compose restart
  • Upgrade: cd ~/.airlock && docker compose pull && docker compose up -d — same compose, newer images.
  • Logs: docker compose logs -f cp or docker compose logs -f console.
  • Volume backup: docker run --rm -v airlock_state:/state -v $(pwd):/backup busybox tar czf /backup/airlock-state.tgz -C / state
  • Reset: docker compose down -v (the -v removes the state volume; you'll get a fresh CP keypair plus token on next startup).

When to use this vs self-hosting-cp.md#

Quick guide to whether you're on the wrong page:

Use this pageUse self-hosting-cp.md
Local laptop / one-VM evalProduction deploy
Just want to see the console workingk8s, multi-region, multi-replica
OK with HTTP on localhostNeed TLS / signed images / cosign
Tear down + start over freelyBacked-up volume, monitoring, alerting
Single-tenant operatorOrg-scoped operators with OIDC

Troubleshooting#

A few common failure modes:

  • docker pull returns "denied" — your PAT isn't authorized for the airlockai org. Re-authorize via Settings → Developer settings → PAT → "Configure SSO".
  • CP refuses to start — check AIRLOCK_CP_ALLOW_LOCALHOST_PUBLIC_URL=true is in .env (required when AIRLOCK_CP_PUBLIC_URL is http://localhost:*).
  • Console can't reach CP — make sure both are on the same compose network (the bundled compose.yaml does this; if you split them onto different stacks, set AIRLOCK_CP_URL on the console explicitly).
  • Token forgotcat ~/.airlock/.env (it's there).

Next steps#