Platform setup
How to Set Up OpenClaw with Docker
Browse more in Platform setup.
All platform setup guides →This guide walks you through how to set up the OpenClaw gateway with Docker and Docker Compose, using the official scripts from the repo. You use the same flow whether you want a throwaway local gateway or a containerized setup on a VPS.
1:18789 with the Control UI wired up.
Prerequisites
- ✓Docker Desktop (or Docker Engine) + Docker Compose v2
- ✓At least 2 GB RAM for image build (`pnpm install` may 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-USER` firewall policy
Steps
- 1
Build the OpenClaw Docker image with the setup script
Start from the repo root and let the provided setup script handle the Docker image build and Compose wiring. This gives you a known-good gateway image and avoids hand-writing your own Docker commands on the first run.
bash./scripts/docker/setup.sh - 2
Use a pre-built OpenClaw image instead of building locally
If your machine is slow or you want to skip local builds, point the setup script at the published image on GitHub Container Registry. This is also useful in CI or on constrained VPS hosts where `pnpm install` might hit RAM limits.
bashexport OPENCLAW_IMAGE="ghcr.io/openclaw/openclaw:latest" ./scripts/docker/setup.sh - 3
Complete the onboarding flow in the setup script
env`. It also starts the gateway via Docker Compose so you have a running service as soon as onboarding finishes.
- 4
Open the Control UI and pair your browser
Once the gateway is up, connect to the Control UI from your host browser to manage agents and settings. env` (or your password if you switched auth modes) so the dashboard can talk to the gateway.
bashdocker compose run --rm openclaw-cli dashboard --no-open - 5
Configure messaging channels from the CLI container
Use the `openclaw-cli` container to add WhatsApp, Telegram, or Discord channels against the running gateway. 1 inside the Docker network.
bash# WhatsApp (QR) docker compose run --rm openclaw-cli channels login # Telegram docker compose run --rm openclaw-cli channels add --channel telegram --token "<token>" # Discord docker compose run --rm openclaw-cli channels add --channel discord --token "<token>" - 6
Run the manual Docker flow for fine-grained control
If you want to see and control each step yourself, use the manual flow instead of the setup script. You build the image, run onboarding and config writes directly via `openclaw-gateway`, then bring the gateway up with Docker Compose.
bashdocker build -t openclaw:local -f Dockerfile . docker compose run --rm --no-deps --entrypoint node openclaw-gateway \ dist/index.js onboard --mode local --no-install-daemon docker compose run --rm --no-deps --entrypoint node openclaw-gateway \ dist/index.js config set --batch-json '[{"path":"gateway.mode","value":"local"},{"path":"gateway.bind","value":"lan"},{"path":"gateway.controlUi.allowedOrigins","value":["http://localhost:18789","http://127.0.0.1:18789"]}]' docker compose up -d openclaw-gateway - 7
Enable agent sandboxing for Docker gateway
When you want tool execution to run in isolated containers, enable the agent sandbox before running the Docker setup. mode` off if it cannot complete.
bashexport OPENCLAW_SANDBOX=1 ./scripts/docker/setup.sh - 8
Install ClawDock shell helpers for day-to-day Docker management
For frequent local development, install the ClawDock helpers so you get `clawdock-start`, `clawdock-stop`, and `clawdock-dashboard` commands. This keeps your Docker workflow short and avoids remembering long `docker compose` invocations.
bashmkdir -p ~/.clawdock && curl -sL https://raw.githubusercontent.com/openclaw/openclaw/main/scripts/clawdock/clawdock-helpers.sh -o ~/.clawdock/clawdock-helpers.sh echo 'source ~/.clawdock/clawdock-helpers.sh' >> ~/.zshrc && source ~/.zshrc
Configuration
| Option | Description | Example |
|---|---|---|
| OPENCLAW_IMAGE | Selects a remote OpenClaw image from a registry instead of building the gateway image locally. | ghcr.io/openclaw/openclaw:latest |
| OPENCLAW_DOCKER_APT_PACKAGES | Installs extra apt packages into the image during build, useful for tools your agents need. | git curl jq |
| OPENCLAW_EXTENSIONS | Pre-installs extension dependencies at build time so they are available inside the container. | my-extension another-extension |
| OPENCLAW_EXTRA_MOUNTS | Adds extra host bind mounts into the containers, using comma-separated source:target[:opts] entries. | /srv/openclaw-extra:/extra-data:ro |
| OPENCLAW_HOME_VOLUME | Persists `/home/node` in a named Docker volume so home-directory state survives container replacement. | openclaw_home |
| OPENCLAW_SANDBOX | Opts in to sandbox bootstrap so agent tool execution runs in isolated Docker containers. | 1 |
| OPENCLAW_DOCKER_SOCKET | Overrides the Docker socket path used for sandbox containers, useful for rootless Docker setups. | /run/user/1000/docker.sock |
| gateway.mode | Controls the gateway mode; `local` keeps the gateway bound to your local environment. | local |
| gateway.bind | Controls how the gateway binds for network access; `lan` lets the host browser and CLI reach the published port. | lan |
| gateway.controlUi.allowedOrigins | Lists which origins can load the Control UI and talk to the gateway. | ["http://localhost:18789","http://127.0.0.1:18789"] |
| agents.defaults.sandbox.mode | Sets when sandboxing is active for agents: off, non-main, or all. | non-main |
| agents.defaults.sandbox.docker.image | Specifies the Docker image used for sandbox containers when running agent tools. | openclaw-sandbox:latest |
| docker.user | Sets the UID:GID inside sandbox containers to match your mounted workspace ownership. | 1000:1000 |
| docker.env.PATH | Overrides the PATH inside sandbox containers so custom tools are discoverable when commands run with `sh -lc`. | /custom/tools/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin |
| PLAYWRIGHT_BROWSERS_PATH | Configures where Playwright downloads browser binaries so they can be persisted via volumes or mounts. | /home/node/.cache/ms-playwright |
Troubleshooting
Image missing or sandbox container not starting
The sandbox image either does not exist or is not referenced correctly, so sandbox containers fail to start. image` at a valid image.
scripts/sandbox-setup.shPermission errors in sandbox
The sandbox container user does not match the ownership of your mounted workspace, so writes fail with EACCES. user` to a UID:GID that matches your host directory or chown the workspace folder.
Custom tools not found in sandbox
Commands run with `sh -lc`, which sources `/etc/profile` and can reset PATH so your custom binaries disappear. d/` in your Dockerfile.
OOM-killed during image build (exit 137)
The VM does not have enough RAM for the build, so the kernel kills `pnpm install` with exit code 137. Move to a machine with at least 2 GB RAM and rerun the build.
Unauthorized or pairing required in Control UI
The dashboard session is not paired with the gateway yet, so the UI shows unauthorized or pairing prompts. Generate a fresh dashboard link, list devices, and approve the pending browser device.
docker compose run --rm openclaw-cli dashboard --no-open
docker compose run --rm openclaw-cli devices list
docker compose run --rm openclaw-cli devices approve <requestId>Gateway target shows ws://172.x.x.x or pairing errors from Docker CLI
The gateway mode or bind is misconfigured, so the CLI points at an internal Docker IP instead of localhost. 1:18789 URL.
docker compose run --rm openclaw-cli config set --batch-json '[{"path":"gateway.mode","value":"local"},{"path":"gateway.bind","value":"lan"}]'
docker compose run --rm openclaw-cli devices list --url ws://127.0.0.1:18789Frequently asked questions
Powered by Mem0
Add persistent memory to OpenClaw
Official Mem0 plugin for OpenClaw keeps context across chats and tools. Smaller prompts, lower cost, better continuity for your agents.