Skip to main content

Production checklist

Before relying on HQ for real work, walk through this list. Most items take under a minute.
1

Pin image versions

Don’t track :latest in production. Pin all images to the same release tag (e.g., v0.1.3) in your .env. See Pinning image versions below.
2

Disable Supabase email signup

In your Supabase project: Authentication → Providers → Email → disable “Allow new users to sign up.” This prevents anyone with your Supabase URL from creating an account. Add users manually via the Supabase dashboard.
3

Enable MFA on your Supabase account

Your Supabase dashboard has full access to every table. Enable multi-factor auth in your Supabase account settings.
4

Use Tailscale or a reverse proxy

Default port bindings are loopback-only (localhost). To access HQ from other devices, use Tailscale (recommended — private, no port exposure) or a reverse proxy with TLS (Caddy, Cloudflare Tunnel, nginx).
5

Generate strong secrets

If you set GATEWAY_AUTH_TOKEN manually, use a strong random value: openssl rand -hex 32. Never reuse secrets across environments.
6

Set up backups

Back up your Supabase database, gateway state volume, and .env file. See Backing up below. At minimum, enable Supabase Pro backups or schedule a weekly pg_dump.
7

Set up monitoring

Check gateway heartbeats in Settings → Gateways and review command history in Settings → System. Set up log forwarding if your infrastructure supports it. See Monitoring below.
8

Review the security model

Read Security model → and SECURITY.md to understand trust boundaries — especially the Docker socket mount and service role key implications.

Updating HQ

Updating is a pull-and-restart — no rebuilds required.
The UI’s Supabase config lives in the workspace registry (runtime, not baked into the image), so updates never require a UI rebuild. Just pull and restart. Update from the UI: Settings → Gateways → hover a gateway row → Update gateway. This runs docker compose pull && up -d on the gateway host via the runner daemon.
Check GitHub releases before updating. If a release includes new migrations, run them in Supabase SQL Editor before pulling the new images. Skipping this step can cause the UI to show a “schema out of date” banner.

Upgrading across versions

When a new HQ version ships with database schema changes, you need to run the new migrations before (or immediately after) pulling the new images. Here’s the full process.

1. Check what changed

Read the release notes for the version you’re upgrading to. Each release lists any new migration files. You can also diff migration files directly:

2. Back up before upgrading

Always back up before applying new migrations. At minimum:

3. Apply new migrations

Open your Supabase project’s SQL Editor and run each new migration file in filename order. All HQ migrations are idempotent (IF NOT EXISTS, CREATE OR REPLACE), so re-running an already-applied migration is safe.
You can check which migrations have been applied by querying the schema version table:
If this table doesn’t exist, you’re on a pre-v0.1.0 install — apply all migrations from 001 onward.

4. Pull and restart

5. Verify

After restarting:
  • The UI should load without a “schema out of date” banner
  • Settings → System should show all services as healthy
  • Settings → Gateways should show your gateway(s) with a green heartbeat

Downgrading

HQ migrations are forward-only. There are no down migrations. If an upgrade breaks something:
  1. Restore your database from the pre-upgrade pg_dump
  2. Pin your images to the previous version tag (see Pinning image versions)
  3. Open an issue on GitHub with the error

Version compatibility

All images in a running stack should be from the same release. Don’t mix a v0.2.0 UI with v0.1.0 gateway images — the UI may reference database columns or RPCs that don’t exist yet. Pin all images to the same tag when you pin any of them.

Backing up

Automatic gateway backups

Since v0.2.1, gateway state (auth tokens, agent configs, secrets, Telegram pairing) is automatically backed up to Supabase Storage on every container shutdown and restored on fresh boot. This means recreated containers, redeployed sandboxes, and volume-loss scenarios recover automatically without manual intervention.
  • Retention: 3 backups per gateway, 7-day max age. Oldest backups are pruned automatically.
  • Restore on boot: When a fresh gateway container starts with no local agent state, it checks Supabase Storage for a previous backup and restores from the newest available. If the newest is corrupted, it falls back to older backups.
  • Manual backups: Trigger a manual backup from Settings → Backups in the UI. This page also shows backup status, timestamps, and lets you delete old backups.
  • Excluded directories: sessions and codex-home are excluded to keep backups small and fast.
Automatic backups cover gateway runtime state (auth, configs, secrets). They do not replace database backups or git remote sync for agent branches — you still need all three layers below.

Manual backup layers

Three things to back up. Don’t skip any of them. (HQ hosted handles backups and updates automatically.)

1. Supabase — workspace data

Supabase stores everything: contacts, tasks, agents, knowledge items, routines, collections, usage history, audit log, and gateway registrations. Losing it means losing your entire workspace.Option A: Supabase built-in backups (Pro tier)Supabase Pro includes daily automatic backups and point-in-time recovery. Enable under Project Settings → Database → Backups. This is the easiest path if you’re on Pro.Option B: pg_dump (free, manual)
Your database password and project ref are in Supabase → Project Settings → Database → Connection string.To restore:
Recommended frequency: daily for active workspaces, weekly for light use.
The gateway-state Docker volume holds everything that lives on the gateway: agent git branches, OpenClaw config, Chrome profiles, desktop shortcuts, auth tokens, plugins, and the VNC password.Losing this volume is less catastrophic than it used to be — automatic backups to Supabase Storage (see above) will restore auth tokens, configs, and secrets on the next boot. However, browser profiles, Chrome sessions, and desktop state are not included in automatic backups. Agents can be reprovisioned from the database, but you’ll lose accumulated browser state.Back up the volume:
This creates a compressed archive in your current directory.Restore from backup:
Better option: git remote sync. Set GIT_REMOTE_URL in .env to push every agent branch to GitHub or Gitea automatically. Even if you lose the Docker volume, the branches survive. See Configuration → Git remote sync.Recommended frequency: weekly for agent state, or enable git remote sync for continuous backup of agent branches.
.env contains GATEWAY_AUTH_TOKEN, optional git credentials, and other secrets. It’s a flat text file and easy to lose track of.Store a copy in:
  • A password manager (1Password, Bitwarden, etc.)
  • An encrypted note
  • Your secure git repo (private, access-controlled)
Never commit .env to a public repo. The file contains keys that give full database access to your workspace.

Monitoring

Container health

All services should show Status: Up (ui, gateway, dispatcher, runner, embedder, file-processor, plugin-runner). If a container is in Restarting state, tail its logs to find the error.

Gateway heartbeat

The gateway daemon writes last_seen_at to Supabase every 30 seconds. The UI shows heartbeat health on Settings → Gateways.
  • Healthy (green) — last_seen_at updated within 90 seconds
  • Stale (amber) — status is ready but heartbeat is old
  • No signal — gateway has never reported (possibly never started)
If you see “Stale”, the runner daemon is likely stopped. Check:

Command history

Settings → System → Commands shows every command the runner has processed, with status, stdout, and stderr. Useful for diagnosing failed provisions or auth flows.

Disk usage

Agent branches, Chrome profiles, and logs accumulate over time:
If the volume is large, the most likely culprit is Chrome profile data. You can clear an agent’s Chrome profile from the agent detail page → Operations → Clear browser profile.

Pinning image versions

By default, HQ tracks :latest. For production installs where stability matters more than freshness:
Then pull and restart:
Pin to the same date tag across all four images — mixing versions can cause incompatibilities.

Restarting individual services

You don’t need to restart the whole stack for most changes:
See Configuration → Section 7 for which variables require which restart.

Uninstalling

docker compose down -v deletes all Docker volumes, including the gateway-state volume with all agent files. Back up first if you want to keep anything.
To also delete the Supabase project: go to Supabase → Settings → General → Delete project.