> ## Documentation Index
> Fetch the complete documentation index at: https://docs.yourhq.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Operations

> How to update, back up, monitor, and maintain your HQ install.

## Production checklist

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

<Steps>
  <Step title="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](#pinning-image-versions) below.
  </Step>

  <Step title="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.
  </Step>

  <Step title="Enable MFA on your Supabase account">
    Your Supabase dashboard has full access to every table. Enable multi-factor auth in your Supabase account settings.
  </Step>

  <Step title="Use Tailscale or a reverse proxy">
    Default port bindings are loopback-only (localhost). To access HQ from other devices, use [Tailscale](/self-host/networking) (recommended — private, no port exposure) or a reverse proxy with TLS (Caddy, Cloudflare Tunnel, nginx).
  </Step>

  <Step title="Generate strong secrets">
    If you set `GATEWAY_AUTH_TOKEN` manually, use a strong random value: `openssl rand -hex 32`. Never reuse secrets across environments.
  </Step>

  <Step title="Set up backups">
    Back up your Supabase database, gateway state volume, and `.env` file. See [Backing up](#backing-up) below. At minimum, enable Supabase Pro backups or schedule a weekly `pg_dump`.
  </Step>

  <Step title="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](#monitoring) below.
  </Step>

  <Step title="Review the security model">
    Read [Security model →](/concepts/security-model) and [SECURITY.md](https://github.com/yourhq/yourhq/blob/main/SECURITY.md) to understand trust boundaries — especially the Docker socket mount and service role key implications.
  </Step>
</Steps>

***

## Updating HQ

Updating is a pull-and-restart — no rebuilds required.

```bash theme={null}
cd ~/.yourhq          # or wherever you installed
docker compose pull   # download latest images
docker compose up -d  # restart with new images
```

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.

<Warning>
  Check [GitHub releases](https://github.com/yourhq/yourhq/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.
</Warning>

***

## 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](https://github.com/yourhq/yourhq/releases) for the version you're upgrading to. Each release lists any new migration files.

You can also diff migration files directly:

```bash theme={null}
# See what migrations were added since your current version
git log v0.1.0..v0.2.0 --oneline -- db/migrations/
```

### 2. Back up before upgrading

Always back up before applying new migrations. At minimum:

```bash theme={null}
# Database
pg_dump \
  "postgresql://postgres:<db-password>@db.<project-ref>.supabase.co:5432/postgres" \
  -Fc -f pre-upgrade-$(date +%Y%m%d).dump

# Gateway state volume
docker run --rm \
  -v yourhq-gateway-state:/src \
  -v $(pwd):/dst \
  alpine tar -czf /dst/gateway-state-pre-upgrade.tar.gz -C /src .
```

### 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.

<Tip>
  You can check which migrations have been applied by querying the schema version table:

  ```sql theme={null}
  SELECT * FROM _schema_version ORDER BY applied_at;
  ```

  If this table doesn't exist, you're on a pre-v0.1.0 install — apply all migrations from `001` onward.
</Tip>

### 4. Pull and restart

```bash theme={null}
cd ~/.yourhq
docker compose pull
docker compose up -d
```

### 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](#pinning-image-versions))
3. Open an issue on [GitHub](https://github.com/yourhq/yourhq/issues) 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.

<Tip>
  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.
</Tip>

### Manual backup layers

Three things to back up. Don't skip any of them. ([HQ hosted](/hosted/getting-started) handles backups and updates automatically.)

<AccordionGroup>
  <Accordion title="1. Supabase — workspace data" icon="database" defaultOpen>
    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)**

    ```bash theme={null}
    pg_dump \
      "postgresql://postgres:<db-password>@db.<project-ref>.supabase.co:5432/postgres" \
      -Fc -f supabase-backup-$(date +%Y%m%d).dump
    ```

    Your database password and project ref are in **Supabase → Project Settings → Database → Connection string**.

    To restore:

    ```bash theme={null}
    pg_restore \
      "postgresql://postgres:<db-password>@db.<project-ref>.supabase.co:5432/postgres" \
      -d postgres supabase-backup-20260101.dump
    ```

    **Recommended frequency:** daily for active workspaces, weekly for light use.
  </Accordion>

  <Accordion title="2. Gateway state volume — agent files" icon="folder">
    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:**

    ```bash theme={null}
    docker run --rm \
      -v yourhq-gateway-state:/src \
      -v $(pwd):/dst \
      alpine tar -czf /dst/gateway-state-$(date +%Y%m%d).tar.gz -C /src .
    ```

    This creates a compressed archive in your current directory.

    **Restore from backup:**

    ```bash theme={null}
    # Stop the gateway first
    docker compose stop gateway dispatcher runner

    # Restore into the volume
    docker run --rm \
      -v yourhq-gateway-state:/dst \
      -v $(pwd):/src \
      alpine sh -c "cd /dst && tar -xzf /src/gateway-state-20260101.tar.gz"

    # Restart
    docker compose up -d
    ```

    **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](/reference/configuration) → Git remote sync.

    **Recommended frequency:** weekly for agent state, or enable git remote sync for continuous backup of agent branches.
  </Accordion>

  <Accordion title="3. .env — infrastructure secrets" icon="key">
    `.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.
  </Accordion>
</AccordionGroup>

***

## Monitoring

### Container health

```bash theme={null}
# Check all container status
docker compose ps

# Tail all logs
docker compose logs -f

# Check a specific service
docker compose logs -f gateway
docker compose logs -f runner
docker compose logs -f dispatcher
```

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:

```bash theme={null}
docker compose logs -f runner | tail -50
```

### 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:

```bash theme={null}
# Check volume sizes
docker system df -v

# Check gateway-state volume specifically
docker run --rm -v yourhq-gateway-state:/data alpine du -sh /data/*
```

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:

```bash theme={null}
# In .env
UI_IMAGE=ghcr.io/yourhq/yourhq-ui:2026.04.20
GATEWAY_IMAGE=ghcr.io/yourhq/yourhq-gateway:2026.04.20
DISPATCHER_IMAGE=ghcr.io/yourhq/yourhq-dispatcher:2026.04.20
RUNNER_IMAGE=ghcr.io/yourhq/yourhq-runner:2026.04.20
```

Then pull and restart:

```bash theme={null}
docker compose pull && docker compose up -d
```

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:

```bash theme={null}
# Restart just the UI (e.g. after changing ALLOWED_ORIGINS)
docker compose restart ui

# Restart gateway after .env changes
docker compose up -d gateway

# Force-recreate a service (e.g. after changing port bindings)
docker compose up -d --force-recreate gateway
```

See [Configuration](/reference/configuration) → Section 7 for which variables require which restart.

***

## Uninstalling

<Warning>
  `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.
</Warning>

```bash theme={null}
cd ~/.yourhq
docker compose down -v   # stops containers and deletes volumes
cd ..
rm -rf .yourhq
```

To also delete the Supabase project: go to **Supabase → Settings → General → Delete project**.
