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.
Configuration
This is the authoritative reference for every environment variable and configuration knob in yourhq. If you’re trying to figure out what a variable does, whether you need to set it, or why a change you made didn’t take effect, start here. Related reading:- Networking — deep dive on
NETWORKING_MODEand host vs container networking - Agents — agent-specific runtime config (not covered here; lives in
agent.jsonper branch) - Features — product-level explanation of workspace features and gateway management
1. Where configuration lives
All stack-level config lives in a single file:.env at the repo root (or at $YOURHQ_HOME/.env, typically ~/.yourhq/.env, if you installed via the curl installer). Docker Compose loads this file automatically — the values are substituted into docker-compose.yml (and the dev overlay docker-compose.dev.yml) at docker compose up time.
The installer (installer/install.sh) prompts for the minimum required values and writes .env for you with sensible defaults for everything else. .env.example is the canonical list of supported keys — if a variable isn’t there, it isn’t read by the stack.
There are two flavors of variable that behave very differently:
- Runtime variables — read by the container process when it starts. Change the value in
.env, rundocker compose up -d <service>, and the new value takes effect. Most variables are runtime. - Build-time variables — baked into the container image when
docker compose buildruns. Changing the value in.envdoes nothing until the image is rebuilt. HQ no longer usesNEXT_PUBLIC_SUPABASE_*for project config; Supabase browser config is injected at runtime from the project registry.
docker compose pull (and falls back to build if the image isn’t in the registry), so on a fresh install the distinction is invisible. It only matters when you edit .env later.
2. Grouped environment variable reference
Each variable below lists: Name / Required / Default / What it does / When to override.2.1 Supabase (managed by the UI, not .env)
The gateway, dispatcher, and runner each read Supabase credentials from two sources in this order:
- Environment variables (
SUPABASE_URL+SUPABASE_SERVICE_ROLE_KEY) if set. - Project registry at
/config/projects.json+/config/secrets.json(written by the UI’s onboarding screen and mounted read-only into the gateway services).
.env for Supabase. The onboarding screen writes the creds to the shared ui-config volume, the gateway polls /config on boot and picks them up automatically.
Use (1) only as an override — e.g. a remote gateway that must always point at a specific project regardless of what the UI’s active project is.
-
SUPABASE_URL— Optional override. No default. If set, takes precedence over the registry. -
SUPABASE_SERVICE_ROLE_KEY— Optional override, secret. No default. If set, takes precedence over the registry. -
EMBEDDING_API_KEY— Optional. Empty. OpenAI API key used by the gateway to embed documents when the knowledge-base vector search is enabled. Override to enable embeddings; leave empty to disable.
/config/projects.json for URL + anon key, /config/secrets.json for service role key). Don’t edit these by hand — use the onboarding screen on first boot, or Settings → Projects afterward.
secrets.json is mode 0644 inside the Docker-managed config volume so the UI, gateway, runner, and dispatcher containers can all read it despite running as different users. The host-level Docker volume directory is the real filesystem boundary. Treat the host and every container in the Compose stack as trusted.
2.2 Gateway identity
These let one Supabase project host multiple independent gateway hosts (your laptop, a Mac mini, a VPS) without them stepping on each other.-
GATEWAY_ID— Required. Defaultdefault. Unique slug per gateway within a Supabase project. Becomes theslugcolumn in thegatewaystable. Override when you bring up a second gateway against the same Supabase (e.g.mac-mini,vps-eu). -
GATEWAY_LABEL— Optional. DefaultPrimary gateway. Human-readable label shown in the UI’s gateway picker. Override for anything you’d show a person. -
WORKSPACE_SLUG— Required. Defaultmy-workspace. The workspace slug you pick in the setup wizard. Used as the prefix for per-agent git branches in the gateway’s local repo (branches are named${WORKSPACE_SLUG}/${agent_slug}). Must match the slug in the UI’s workspace record — if you change it after install, rename branches accordingly. -
COMPOSE_PROJECT— Optional. Defaultyourhq. Namespaces Compose containers and volumes (you’ll seeyourhq-ui,yourhq-gateway, etc.). Override if you’re running two parallel stacks on one host (e.g.yourhq-staging).
2.3 Networking
Host-level networking decisions: local-only vs Tailscale vs public HTTPS. The installer sets all five of these together based on the mode you pick. See Networking for the full topology.-
NETWORKING_MODE— Required. Defaultlocal. One oflocal/tailscale/public. Purely informational for the containers — it’s written into thegateways.meta.networking_modecolumn so the UI knows how to build URLs. The actual binding behavior is controlled by the*_HOST_PORTvariables below. -
HOST_REACHABLE_URL— Required. Defaulthttp://localhost. The URL users hit in their browser, minus the port. Installer sets this tohttp://localhostforlocal,http://<host-ts-ip>fortailscale, orhttps://<your-domain>forpublic. The gateway writes it into Supabase so the UI can build links to noVNC and the files-API. -
UI_HOST_PORT— Optional. Default127.0.0.1:3000(loopback-only, safe). The installer flips this to0.0.0.0:3000when you pick Tailscale or Public mode. Manually override to0.0.0.0:3000when you want the host’s network interfaces (Tailscale, public) to decide reachability. -
NOVNC_HOST_PORT— Optional. Same shape asUI_HOST_PORT, default127.0.0.1:6901. Installer flips to0.0.0.0:6901for Tailscale/Public modes. Keep loopback-only unless you trust the host’s network — noVNC only has a generated VNC password as auth and should never be on the public internet without a reverse proxy. -
FILES_API_HOST_PORT— Optional. Default127.0.0.1:18790(loopback-only). The files-API only needs to be reachable from outside the host when the UI lives on a different machine (Tailscale cross-host). Single-host installs can leave it on loopback — the UI reaches it internally via Docker DNS (http://gateway:18790). -
NOVNC_BIND— Optional. Defaultlocal. One oflocal(websockify binds0.0.0.0:6901inside the container, Docker port-mapping decides real exposure) oroff(don’t start noVNC at all). Override tooffif you don’t need remote desktop. -
VNC_PASSWORD— Optional, secret. Empty. The VNC password for the in-container desktop. Auto-generated on first boot if empty; the generated value is saved to$OPENCLAW_HOME/.vnc-passwordinside thegateway-statevolume. Override if you want a specific known password.
2.4 Files-API (UI file browser)
The gateway runs an HTTP API (files_api.py) that the UI calls to read/write files inside per-agent git worktrees. Auth is a shared bearer token.
-
GATEWAY_AUTH_TOKEN— Required (secret) if you want the file browser. Empty by default. Shared secret between the UI and the gateway’s files-API. Generate withopenssl rand -hex 32. Must be identical in both theuiandgatewayservices — since both read the same.env, this is automatic. If empty, the gateway doesn’t start the files-API at all. -
GATEWAY_URL— Optional. Defaulthttp://gateway:18790. Where the UI reaches the files-API. Leave at the default for same-host Compose stacks (uses Docker’s internal DNS). Override tohttp://<gateway-host-ts-ip>:18790when UI and gateway live on different machines connected over Tailscale. -
FILES_API_BIND— Optional. Defaultdocker. One ofdocker(listens on the Docker internal network only — UI reaches viagateway:18790),any(binds0.0.0.0inside container; host port-mapping decides exposure), oroff(disable the files-API). Override toanywhen the UI is on a remote host. -
FILES_API_PORT— Optional. Default18790. In-container port for the files-API. Rarely worth changing.
2.5 Templates
TEMPLATES_SOURCE— Optional. Empty. When empty, the gateway seeds its bare repo from the templates bundled in/opt/templatesinside the image. Override withgit+https://github.com/your-org/your-templates.gitto seed from your own repo instead. Only read on first boot when the gateway creates its bare repo — changing it later won’t re-seed existing branches.
2.6 Git remote sync (optional, backup)
Lets the gateway push per-agent branches to an external git remote so your agents’ memory and skills are backed up and optionally reachable from other devices. Two configuration paths — pick one. Path A: generic remote (works for any git host — GitHub, Gitea, self-hosted)-
GIT_REMOTE_URL— Optional. Empty. If set, added as theoriginremote of the gateway’s bare repo. Examples:https://x-access-token:[email protected]/org/repo.git,[email protected]:org/repo.git,https://git.example.com/agents.git. -
GIT_DEPLOY_KEY— Optional, secret. Empty. SSH private key (full multiline PEM, keep surrounding double-quotes in.envso newlines survive). Only needed for SSH remotes.
GIT_REMOTE_URL is empty AND all three GITHUB_* vars below are set, the gateway synthesizes https://x-access-token:[email protected]/$GITHUB_REPO_OWNER/$GITHUB_REPO_NAME.git at boot.
-
GITHUB_TOKEN— Optional, secret. Empty. Fine-grained PAT with Contents: Read and write on the target repo. Classic PATs withreposcope also work. -
GITHUB_REPO_OWNER— Optional. Empty. GitHub user or org that owns the repo. -
GITHUB_REPO_NAME— Optional. Empty. Repo name only (no owner prefix).
post-commit git hook on the bare repo that async-pushes every commit to origin. No scheduled sync, no batching — every commit (from add-agent.sh, file-browser edits, or an agent calling save_progress) lands on the remote within seconds. The runner also runs a GIT_SYNC_INTERVAL-second backup sweep that commits dirty worktrees and fast-forwards any branches that moved on the remote.
Without a remote, all of this still works locally — commits just don’t leave the gateway’s volume.
2.8 Runtime tuning
Control loops in the dispatcher and runner daemons. Defaults are sensible; override only when instrumenting or tuning latency.-
POLL_INTERVAL— Optional. Default30. Seconds between command-queue polls by the runner. Lower for faster command pickup at the cost of more Supabase requests. -
COMMAND_TIMEOUT— Optional. Default120. Seconds a single command can run before the runner kills it and marks it failed. -
RECONCILE_INTERVAL— Optional. Default60. Seconds between dispatcher reconciliation passes (checking for orphaned inbox items, stale leases, etc.). -
WAKE_COOLDOWN— Optional. Default30. Seconds the dispatcher waits before re-waking an agent that just failed. -
GIT_SYNC_INTERVAL— Optional. Default1800(30 min). Seconds between backup-sweep passes in the runner (commits dirty worktrees, fast-forwards branches that moved on the remote). Set to0to disable the sweep entirely — event-driven commits and the post-commit auto-push still work.
2.9 Image overrides
Pin specific image tags for reproducible production deploys. All four default to:latest.
UI_IMAGE— Optional. Defaultghcr.io/yourhq/yourhq-ui:latest.GATEWAY_IMAGE— Optional. Defaultghcr.io/yourhq/yourhq-gateway:latest.DISPATCHER_IMAGE— Optional. Defaultghcr.io/yourhq/yourhq-dispatcher:latest.RUNNER_IMAGE— Optional. Defaultghcr.io/yourhq/yourhq-runner:latest.
ghcr.io/yourhq/yourhq-<svc>:2026.04.20 (or similar date-pinned tag) for production. Don’t pin in dev — you want to track :latest.
2.10 Codespaces / reverse-proxy origin allowlist
Next.js enforces an origin allowlist on server actions and form submissions. When the UI is fronted by a reverse proxy or GitHub Codespaces port-forward, the apparent origin differs fromlocalhost:3000 and requests get rejected as CSRF. These variables extend the allowlist.
-
CODESPACE_NAME— Auto-set by GitHub Codespaces. Don’t set manually. -
GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN— Auto-set by GitHub Codespaces. Don’t set manually. Combined withCODESPACE_NAMEby the UI to whitelist the forwarded URL. -
ALLOWED_ORIGINS— Optional. Empty. Comma-separated list of extra origins to allow (e.g.https://hq.example.com,https://staging.example.com). Set this when running behind any non-Codespaces reverse proxy with a public domain.
3. Runtime Supabase config — no more NEXT_PUBLIC bake-in
The UI used to bakeNEXT_PUBLIC_SUPABASE_* into the client bundle at build time, which meant every user had to docker compose build ui locally to stamp in their own Supabase values. That’s gone.
Now the UI reads its Supabase config at runtime from the project registry (/config/projects.json + /config/secrets.json). The root layout renders a <script>window.__HQ_CONFIG__ = {...}</script> tag based on the active project’s cookie, so the client bundle picks up whoever’s connected without a rebuild.
Practical consequences:
- The GHCR
yourhq-ui:latestimage works for every user. Nodocker compose build uirequired — ever. - Changing Supabase creds is a UI action (Settings → Projects → Rotate), not a rebuild.
NEXT_PUBLIC_SUPABASE_URLandNEXT_PUBLIC_SUPABASE_ANON_KEYenv vars are no longer read by the UI. Leave them unset.
4. Secrets handling
Every secret lives in plaintext in.env on disk. The installer chmod 600 the file, which is the only layer of protection. Don’t commit .env, don’t paste it into issues, don’t ship it in backups unencrypted.
If one of these leaks:
-
SUPABASE_SERVICE_ROLE_KEY— bypasses RLS and can read/write every row. High severity. Rotate in Supabase dashboard (Project Settings → API → “Generate new service_role key”). Update the affected project in Settings → Projects, or update.envif you use env overrides. Restart gateway services after changing env overrides. Auditaudit_logfor suspicious activity. -
UI anon key (stored in
/config/projects.jsonper project) — subject to RLS, so damage is bounded by your policies. Rotate in the Supabase dashboard, then update it via Settings → Projects → the affected project in the UI. -
GATEWAY_AUTH_TOKEN— auth between UI and files-API. Rotate by picking a new value (openssl rand -hex 32), writing it to.env, and runningdocker compose up -d ui gateway(both services must restart together so they agree on the token). -
GIT_DEPLOY_KEY— rotate in the git host (GitHub → repo settings → Deploy keys), put the new key in.env, thendocker compose up -d gateway. The gateway recreates~/.ssh/openclaw_deploy_keyif it’s missing, but it doesn’t overwrite an existing one — you may need todocker compose exec gateway rm /home/openclaw/.ssh/openclaw_deploy_keyfirst. -
GITHUB_TOKEN— rotate the PAT on GitHub (or revoke it), update.env, thendocker compose up -d gatewayso the entrypoint rebuilds the remote URL with the new token. Existing commits stay local even if the token is revoked — they push to the new remote on the next boot. -
VNC_PASSWORD— rotate by changing the value in.env, then delete the existing hash:docker compose exec gateway rm /home/openclaw/.vnc/passwd, thendocker compose up -d gateway. -
TAILSCALE_AUTH_KEY— host-level, not container-level. The stack no longer runs Tailscale inside any container. The auth key is used once by the installer to runtailscale upon the host. If leaked, revoke in the Tailscale admin console (Settings → Keys) and generate a new one — no container restart needed. Use single-use keys in production and reusable keys only for convenience during setup.
5. Configuring for development
docker-compose.dev.yml is an overlay that runs the UI in next dev mode with source mounted for live-reload, and mounts the gateway daemons from source so edits take effect on restart (no rebuild). Usage:
node:24-slim instead of the prebuilt UI image). Your .env works as-is. Supabase creds for the UI come from the project registry in both modes, so there’s no “did I rebuild” confusion.
6. First-boot setup (non-env configuration)
A lot of yourhq’s configuration is runtime-configurable via the UI, not via environment variables. Once the stack is up and you’ve logged in, visit:-
/setup— the six-step workspace setup wizard. Seedsworkspace(name, slug, owner profile),pipeline_stages,field_definitions, and initialstreamsin one RPC call. New workspaces are redirected here automatically untilworkspace.initialized = true. -
/dashboard/settings— add or edit pipeline stages, custom field definitions, streams, automations, and agent identities after the initial setup. Most per-workspace behavior lives here, not in.env. -
/dashboard/agents— the agent creation wizard (three steps: template → identity → Telegram). See Agents for agent-specific configuration (each agent has its ownagent.jsoncommitted to its git branch).
.env.
7. Changing configuration after install
Edit.env, then run the appropriate Compose command to pick up the change. The right command depends on which service owns the variable and whether it’s build-time or runtime.
UI runtime variables (non-NEXT_PUBLIC_*)
SUPABASE_SERVICE_ROLE_KEY, GATEWAY_URL, GATEWAY_AUTH_TOKEN, ALLOWED_ORIGINS:
UI project config (no rebuild required)
Supabase URL, anon key, service role key per project live in the project registry on theui-config volume, not in .env. Change them via the UI (Settings → Projects → Edit / Rotate) — takes effect immediately on the next request.
Gateway variables
TEMPLATES_SOURCE, GIT_REMOTE_URL, GIT_DEPLOY_KEY, GITHUB_TOKEN, GITHUB_REPO_OWNER, GITHUB_REPO_NAME, GATEWAY_AUTH_TOKEN, FILES_API_BIND, FILES_API_PORT, NOVNC_BIND, VNC_PASSWORD, NETWORKING_MODE, HOST_REACHABLE_URL:
TEMPLATES_SOURCE is only read on first boot when the bare repo is seeded. Changing it later has no effect unless you also wipe the gateway-state volume (destructive — you lose all agent branches).
Dispatcher / runner variables
POLL_INTERVAL, COMMAND_TIMEOUT, RECONCILE_INTERVAL, WAKE_COOLDOWN:
Networking / port-binding changes
UI_HOST_PORT, NOVNC_HOST_PORT, FILES_API_HOST_PORT — changing a port binding doesn’t register with a plain up -d; Compose considers the container “already running” with no relevant change. Force recreation:
Compose project / gateway identity
COMPOSE_PROJECT, GATEWAY_ID — changing either creates new containers and (for COMPOSE_PROJECT) new volumes. Your old stack’s state is orphaned but not deleted. Only change these when you actually want a fresh namespace; otherwise the safer path is to leave them alone.
Image overrides
UI_IMAGE, GATEWAY_IMAGE, DISPATCHER_IMAGE, RUNNER_IMAGE:
Gateway Supabase keys
Changing the gateway’s Supabase connection (SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY) affects the gateway, dispatcher, and runner. UI Supabase creds live in the project registry and don’t need any restart:
Troubleshooting checklist
- “The UI loads but login fails” — the active project in the registry may have wrong creds. Open Settings → Projects → Edit or Rotate to fix, no restart needed.
- “File browser says 401 / auth error” —
GATEWAY_AUTH_TOKENdiffers between UI and gateway, or is empty. Set it identically in.envand rundocker compose up -d ui gateway. - “Changed the port but the old one still works” — port bindings need
--force-recreate(section 7). - “Changed
TEMPLATES_SOURCEbut I still see old templates” — it’s only read on first boot. See section 2.5. - “Gateway keeps trying to reach the wrong URL” —
HOST_REACHABLE_URLis written into Supabase by the gateway at startup; fix.envand restart the gateway, not the UI.