Is Docker right for me?
- Yes: you want an isolated, throwaway gateway environment or to run OpenClaw on a host without local installs.
- No: you are running on your own machine and just want the fastest dev loop. Use the normal install flow instead.
- Sandboxing note: the default sandbox backend uses Docker when sandboxing is enabled, but sandboxing is off by default and does not require the full gateway to run in Docker. SSH and OpenShell sandbox backends are also available. See Sandboxing.
Prerequisites
- Docker Desktop (or Docker Engine) + Docker Compose v2
- At least 2 GB RAM for image build (
pnpm installmay be OOM-killed on 1 GB hosts with exit 137) - Enough disk for images and logs
- If running on a VPS/public host, review
Security hardening for network exposure,
especially Docker
DOCKER-USERfirewall policy.
Containerized gateway
Build the image
From the repo root, run the setup script:This builds the gateway image locally. To use a pre-built image instead:Pre-built images are published at the
GitHub Container Registry.
Common tags:
main, latest, <version> (e.g. 2026.2.26).Complete onboarding
The setup script runs onboarding automatically. It will:
- prompt for provider API keys
- generate a gateway token and write it to
.env - start the gateway via Docker Compose
openclaw-gateway directly. openclaw-cli is for commands you run after
the gateway container already exists.Open the Control UI
Open
http://127.0.0.1:18789/ in your browser and paste the configured
shared secret into Settings. The setup script writes a token to .env by
default; if you switch the container config to password auth, use that
password instead.Need the URL again?Manual flow
If you prefer to run each step yourself instead of using the setup script:Run
docker compose from the repo root. If you enabled OPENCLAW_EXTRA_MOUNTS
or OPENCLAW_HOME_VOLUME, the setup script writes docker-compose.extra.yml;
include it with -f docker-compose.yml -f docker-compose.extra.yml.Because
openclaw-cli shares openclaw-gateway’s network namespace, it is a
post-start tool. Before docker compose up -d openclaw-gateway, run onboarding
and setup-time config writes through openclaw-gateway with
--no-deps --entrypoint node.Environment variables
The setup script accepts these optional environment variables:| Variable | Purpose |
|---|---|
OPENCLAW_IMAGE | Use a remote image instead of building locally |
OPENCLAW_DOCKER_APT_PACKAGES | Install extra apt packages during build (space-separated) |
OPENCLAW_EXTENSIONS | Pre-install plugin deps at build time (space-separated names) |
OPENCLAW_EXTRA_MOUNTS | Extra host bind mounts (comma-separated source:target[:opts]) |
OPENCLAW_HOME_VOLUME | Persist /home/node in a named Docker volume |
OPENCLAW_SANDBOX | Opt in to sandbox bootstrap (1, true, yes, on) |
OPENCLAW_DOCKER_SOCKET | Override Docker socket path |
OPENCLAW_DISABLE_BONJOUR | Disable Bonjour/mDNS advertising (defaults to 1 for Docker) |
OPENCLAW_DISABLE_BUNDLED_SOURCE_OVERLAYS | Disable bundled plugin source bind-mount overlays |
OTEL_EXPORTER_OTLP_ENDPOINT | Shared OTLP/HTTP collector endpoint for OpenTelemetry export |
OTEL_EXPORTER_OTLP_*_ENDPOINT | Signal-specific OTLP endpoints for traces, metrics, or logs |
OTEL_EXPORTER_OTLP_PROTOCOL | OTLP protocol override. Only http/protobuf is supported today |
OTEL_SERVICE_NAME | Service name used for OpenTelemetry resources |
OTEL_SEMCONV_STABILITY_OPT_IN | Opt in to latest experimental GenAI semantic attributes |
OPENCLAW_OTEL_PRELOADED | Skip starting a second OpenTelemetry SDK when one is preloaded |
OPENCLAW_EXTRA_MOUNTS=/path/to/fork/extensions/synology-chat:/app/extensions/synology-chat:ro.
That mounted source directory overrides the matching compiled
/app/dist/extensions/synology-chat bundle for the same plugin id.
Observability
OpenTelemetry export is outbound from the Gateway container to your OTLP collector. It does not require a published Docker port. If you build the image locally and want the bundled OpenTelemetry exporter available inside the image, include its runtime dependencies:diagnostics-otel plugin source. Depending on the image and cache state, the
Gateway may still stage plugin-local OpenTelemetry runtime dependencies the
first time the plugin is enabled, so allow that first boot to reach the package
registry or prewarm the image in your release lane. To enable export, allow and
enable the diagnostics-otel plugin in config, then set
diagnostics.otel.enabled=true or use the config example in
OpenTelemetry export. Collector auth headers are
configured through diagnostics.otel.headers, not through Docker environment
variables.
Prometheus metrics use the already-published Gateway port. Enable the
diagnostics-prometheus plugin, then scrape:
/metrics port or unauthenticated reverse-proxy path. See
Prometheus metrics.
Health checks
Container probe endpoints (no auth required):HEALTHCHECK that pings /healthz.
If checks keep failing, Docker marks the container as unhealthy and
orchestration systems can restart or replace it.
Authenticated deep health snapshot:
LAN vs loopback
scripts/docker/setup.sh defaults OPENCLAW_GATEWAY_BIND=lan so host access to
http://127.0.0.1:18789 works with Docker port publishing.
lan(default): host browser and host CLI can reach the published gateway port.loopback: only processes inside the container network namespace can reach the gateway directly.
Use bind mode values in
gateway.bind (lan / loopback / custom /
tailnet / auto), not host aliases like 0.0.0.0 or 127.0.0.1.Host Local Providers
When OpenClaw runs in Docker,127.0.0.1 inside the container is the container
itself, not your host machine. Use host.docker.internal for AI providers that
run on the host:
| Provider | Host default URL | Docker setup URL |
|---|---|---|
| LM Studio | http://127.0.0.1:1234 | http://host.docker.internal:1234 |
| Ollama | http://127.0.0.1:11434 | http://host.docker.internal:11434 |
docker-compose.yml maps host.docker.internal to
Docker’s host gateway for Linux Docker Engine. Docker Desktop already provides
the same hostname on macOS and Windows.
Host services must also listen on an address reachable from Docker:
docker run command, add the same host
mapping yourself, for example
--add-host=host.docker.internal:host-gateway.
Bonjour / mDNS
Docker bridge networking usually does not forward Bonjour/mDNS multicast (224.0.0.251:5353) reliably. The bundled Compose setup therefore defaults
OPENCLAW_DISABLE_BONJOUR=1 so the Gateway does not crash-loop or repeatedly
restart advertising when the bridge drops multicast traffic.
Use the published Gateway URL, Tailscale, or wide-area DNS-SD for Docker hosts.
Set OPENCLAW_DISABLE_BONJOUR=0 only when running with host networking, macvlan,
or another network where mDNS multicast is known to work.
For gotchas and troubleshooting, see Bonjour discovery.
Storage and persistence
Docker Compose bind-mountsOPENCLAW_CONFIG_DIR to /home/node/.openclaw and
OPENCLAW_WORKSPACE_DIR to /home/node/.openclaw/workspace, so those paths
survive container replacement.
That mounted config directory is where OpenClaw keeps:
openclaw.jsonfor behavior configagents/<agentId>/agent/auth-profiles.jsonfor stored provider OAuth/API-key auth.envfor env-backed runtime secrets such asOPENCLAW_GATEWAY_TOKEN
media/, session JSONL files, cron/runs/*.jsonl,
and rolling file logs under /tmp/openclaw/.
Shell helpers (optional)
For easier day-to-day Docker management, installClawDock:
scripts/shell-helpers/clawdock-helpers.sh raw path, rerun the install command above so your local helper file tracks the new location.
Then use clawdock-start, clawdock-stop, clawdock-dashboard, etc. Run
clawdock-help for all commands.
See ClawDock for the full helper guide.
Enable agent sandbox for Docker gateway
Enable agent sandbox for Docker gateway
docker.sock only after sandbox prerequisites pass. If
sandbox setup cannot complete, the script resets agents.defaults.sandbox.mode
to off.Automation / CI (non-interactive)
Automation / CI (non-interactive)
Disable Compose pseudo-TTY allocation with
-T:Shared-network security note
Shared-network security note
Permissions and EACCES
Permissions and EACCES
The image runs as
node (uid 1000). If you see permission errors on
/home/node/.openclaw, make sure your host bind mounts are owned by uid 1000:Faster rebuilds
Faster rebuilds
Order your Dockerfile so dependency layers are cached. This avoids re-running
pnpm install unless lockfiles change:Power-user container options
Power-user container options
The default image is security-first and runs as non-root
node. For a more
full-featured container:- Persist
/home/node:export OPENCLAW_HOME_VOLUME="openclaw_home" - Bake system deps:
export OPENCLAW_DOCKER_APT_PACKAGES="git curl jq" - Install Playwright browsers:
- Persist browser downloads: set
PLAYWRIGHT_BROWSERS_PATH=/home/node/.cache/ms-playwrightand useOPENCLAW_HOME_VOLUMEorOPENCLAW_EXTRA_MOUNTS.
OpenAI Codex OAuth (headless Docker)
OpenAI Codex OAuth (headless Docker)
If you pick OpenAI Codex OAuth in the wizard, it opens a browser URL. In
Docker or headless setups, copy the full redirect URL you land on and paste
it back into the wizard to finish auth.
Base image metadata
Base image metadata
The main Docker runtime image uses
node:24-bookworm-slim and publishes OCI
base-image annotations including org.opencontainers.image.base.name,
org.opencontainers.image.source, and others. The Node base digest is
refreshed through Dependabot Docker base-image PRs; release builds do not run
a distro upgrade layer. See
OCI image annotations.Running on a VPS?
See Hetzner (Docker VPS) and Docker VM Runtime for shared VM deployment steps including binary baking, persistence, and updates.Agent sandbox
Whenagents.defaults.sandbox is enabled with the Docker backend, the gateway
runs agent tool execution (shell, file read/write, etc.) inside isolated Docker
containers while the gateway itself stays on the host. This gives you a hard wall
around untrusted or multi-tenant agent sessions without containerizing the entire
gateway.
Sandbox scope can be per-agent (default), per-session, or shared. Each scope
gets its own workspace mounted at /workspace. You can also configure
allow/deny tool policies, network isolation, resource limits, and browser
containers.
For full configuration, images, security notes, and multi-agent profiles, see:
- Sandboxing — complete sandbox reference
- OpenShell — interactive shell access to sandbox containers
- Multi-Agent Sandbox and Tools — per-agent overrides
Quick enable
Troubleshooting
Image missing or sandbox container not starting
Image missing or sandbox container not starting
Build the sandbox image with
scripts/sandbox-setup.sh
or set agents.defaults.sandbox.docker.image to your custom image.
Containers are auto-created per session on demand.Permission errors in sandbox
Permission errors in sandbox
Set
docker.user to a UID:GID that matches your mounted workspace ownership,
or chown the workspace folder.Custom tools not found in sandbox
Custom tools not found in sandbox
OpenClaw runs commands with
sh -lc (login shell), which sources
/etc/profile and may reset PATH. Set docker.env.PATH to prepend your
custom tool paths, or add a script under /etc/profile.d/ in your Dockerfile.OOM-killed during image build (exit 137)
OOM-killed during image build (exit 137)
The VM needs at least 2 GB RAM. Use a larger machine class and retry.
Unauthorized or pairing required in Control UI
Unauthorized or pairing required in Control UI
Gateway target shows ws://172.x.x.x or pairing errors from Docker CLI
Gateway target shows ws://172.x.x.x or pairing errors from Docker CLI
Reset gateway mode and bind:
Related
- Install Overview — all installation methods
- Podman — Podman alternative to Docker
- ClawDock — Docker Compose community setup
- Updating — keeping OpenClaw up to date
- Configuration — gateway configuration after install