Running OpenClaw in Docker
How to get OpenClaw running in a Docker container for local development and testing the Paperclip OpenClaw adapter integration.
Automated Join Smoke Test (Recommended First)
Section titled “Automated Join Smoke Test (Recommended First)”Paperclip includes an end-to-end join smoke harness:
pnpm smoke:openclaw-joinThe harness automates:
- invite creation (
allowedJoinTypes=agent) - OpenClaw agent join request (
adapterType=openclaw) - board approval
- one-time API key claim (including invalid/replay claim checks)
- wakeup callback delivery to a dockerized OpenClaw-style webhook receiver
By default, this uses a preconfigured Docker receiver image (docker/openclaw-smoke) so the run is deterministic and requires no manual OpenClaw config edits.
Permissions note:
- The harness performs board-governed actions (invite creation, join approval, wakeup of the new agent).
- In authenticated mode, provide board/operator auth or the run exits early with an explicit permissions error.
One-Command OpenClaw Gateway UI (Manual Docker Flow)
Section titled “One-Command OpenClaw Gateway UI (Manual Docker Flow)”To spin up OpenClaw in Docker and print a host-browser dashboard URL in one command:
pnpm smoke:openclaw-docker-uiDefault behavior is zero-flag: you can run the command as-is with no pairing-related env vars.
What this command does:
- clones/updates
openclaw/openclawin/tmp/openclaw-docker - builds
openclaw:local(unlessOPENCLAW_BUILD=0) - writes isolated smoke config under
~/.openclaw-paperclip-smoke/openclaw.jsonand Docker.env - pins agent model defaults to OpenAI (
openai/gpt-5.2with OpenAI fallback) - starts
openclaw-gatewayvia Compose (with required/tmptmpfs override) - probes and prints a Paperclip host URL that is reachable from inside OpenClaw Docker
- waits for health and prints:
http://127.0.0.1:18789/#token=...
- disables Control UI device pairing by default for local smoke ergonomics
Environment knobs:
OPENAI_API_KEY(required; loaded from env or~/.secrets)OPENCLAW_DOCKER_DIR(default/tmp/openclaw-docker)OPENCLAW_GATEWAY_PORT(default18789)OPENCLAW_GATEWAY_TOKEN(default random)OPENCLAW_BUILD=0to skip rebuildOPENCLAW_OPEN_BROWSER=1to auto-open the URL on macOSOPENCLAW_DISABLE_DEVICE_AUTH=1(default) disables Control UI device pairing for local smokeOPENCLAW_DISABLE_DEVICE_AUTH=0keeps pairing enabled (then approve browser withdevicesCLI commands)OPENCLAW_MODEL_PRIMARY(defaultopenai/gpt-5.2)OPENCLAW_MODEL_FALLBACK(defaultopenai/gpt-5.2-chat-latest)OPENCLAW_CONFIG_DIR(default~/.openclaw-paperclip-smoke)OPENCLAW_RESET_STATE=1(default) resets smoke agent state on each run to avoid stale auth/session driftPAPERCLIP_HOST_PORT(default3100)PAPERCLIP_HOST_FROM_CONTAINER(defaulthost.docker.internal)
Authenticated mode
Section titled “Authenticated mode”If your Paperclip deployment is authenticated, provide auth context:
PAPERCLIP_AUTH_HEADER="Bearer <token>" pnpm smoke:openclaw-join# orPAPERCLIP_COOKIE="your_session_cookie=..." pnpm smoke:openclaw-joinNetwork topology tips
Section titled “Network topology tips”- Local same-host smoke: default callback uses
http://127.0.0.1:<port>/webhook. - Inside OpenClaw Docker,
127.0.0.1points to the container itself, not your host Paperclip server. - For invite/onboarding URLs consumed by OpenClaw in Docker, use the script-printed Paperclip URL (typically
http://host.docker.internal:3100). - If Paperclip rejects the container-visible host with a hostname error, allow it from host:
pnpm paperclipai allowed-hostname host.docker.internalThen restart Paperclip and rerun the smoke script.
- Docker/remote OpenClaw: prefer a reachable hostname (Docker host alias, Tailscale hostname, or public domain).
- Authenticated/private mode: ensure hostnames are in the allowed list when required:
pnpm paperclipai allowed-hostname <host>Prerequisites
Section titled “Prerequisites”- Docker Desktop v29+ (with Docker Sandbox support)
- 2 GB+ RAM available for the Docker image build
- API keys in
~/.secrets(at minimumOPENAI_API_KEY)
Option A: Docker Sandbox (Recommended)
Section titled “Option A: Docker Sandbox (Recommended)”Docker Sandbox provides better isolation (microVM-based) and simpler setup than Docker Compose. Requires Docker Desktop v29+ / Docker Sandbox v0.12+.
# 1. Clone the OpenClaw repo and build the imagegit clone https://github.com/openclaw/openclaw.git /tmp/openclaw-dockercd /tmp/openclaw-dockerdocker build -t openclaw:local -f Dockerfile .
# 2. Create the sandbox using the built imagedocker sandbox create --name openclaw -t openclaw:local shell ~/.openclaw/workspace
# 3. Allow network access to OpenAI APIdocker sandbox network proxy openclaw \ --allow-host api.openai.com \ --allow-host localhost
# 4. Write the config inside the sandboxdocker sandbox exec openclaw sh -c 'mkdir -p /home/node/.openclaw/workspace /home/node/.openclaw/identity /home/node/.openclaw/credentialscat > /home/node/.openclaw/openclaw.json << INNEREOF{ "gateway": { "mode": "local", "port": 18789, "bind": "loopback", "auth": { "mode": "token", "token": "sandbox-dev-token-12345" }, "controlUi": { "enabled": true } }, "agents": { "defaults": { "model": { "primary": "openai/gpt-5.2", "fallbacks": ["openai/gpt-5.2-chat-latest"] }, "workspace": "/home/node/.openclaw/workspace" } }}INNEREOFchmod 600 /home/node/.openclaw/openclaw.json'
# 5. Start the gateway (pass your API key from ~/.secrets)source ~/.secretsdocker sandbox exec -d \ -e OPENAI_API_KEY="$OPENAI_API_KEY" \ -w /app openclaw \ node dist/index.js gateway --bind loopback --port 18789
# 6. Wait ~15 seconds, then verifysleep 15docker sandbox exec openclaw curl -s -o /dev/null -w "%{http_code}" http://127.0.0.1:18789/# Should print: 200
# 7. Check statusdocker sandbox exec -e OPENAI_API_KEY="$OPENAI_API_KEY" -w /app openclaw \ node dist/index.js statusSandbox Management
Section titled “Sandbox Management”# List sandboxesdocker sandbox ls
# Shell into the sandboxdocker sandbox exec -it openclaw bash
# Stop the sandbox (preserves state)docker sandbox stop openclaw
# Remove the sandboxdocker sandbox rm openclaw
# Check sandbox versiondocker sandbox versionOption B: Docker Compose (Fallback)
Section titled “Option B: Docker Compose (Fallback)”Use this if Docker Sandbox is not available (Docker Desktop < v29).
# 1. Clone the OpenClaw repogit clone https://github.com/openclaw/openclaw.git /tmp/openclaw-dockercd /tmp/openclaw-docker
# 2. Build the Docker image (~5-10 min on first run)docker build -t openclaw:local -f Dockerfile .
# 3. Create config directoriesmkdir -p ~/.openclaw/workspace ~/.openclaw/identity ~/.openclaw/credentialschmod 700 ~/.openclaw ~/.openclaw/credentials
# 4. Generate a gateway tokenexport OPENCLAW_GATEWAY_TOKEN=$(openssl rand -hex 32)echo "Your gateway token: $OPENCLAW_GATEWAY_TOKEN"
# 5. Create the config filecat > ~/.openclaw/openclaw.json << EOF{ "gateway": { "mode": "local", "port": 18789, "bind": "lan", "auth": { "mode": "token", "token": "$OPENCLAW_GATEWAY_TOKEN" }, "controlUi": { "enabled": true, "allowedOrigins": ["http://127.0.0.1:18789"] } }, "env": { "OPENAI_API_KEY": "\${OPENAI_API_KEY}" }, "agents": { "defaults": { "model": { "primary": "openai/gpt-5.2", "fallbacks": ["openai/gpt-5.2-chat-latest"] }, "workspace": "/home/node/.openclaw/workspace" } }}EOFchmod 600 ~/.openclaw/openclaw.json
# 6. Create the .env file (load API keys from ~/.secrets)source ~/.secretscat > .env << EOFOPENCLAW_CONFIG_DIR=$HOME/.openclawOPENCLAW_WORKSPACE_DIR=$HOME/.openclaw/workspaceOPENCLAW_GATEWAY_PORT=18789OPENCLAW_BRIDGE_PORT=18790OPENCLAW_GATEWAY_BIND=lanOPENCLAW_GATEWAY_TOKEN=$OPENCLAW_GATEWAY_TOKENOPENCLAW_IMAGE=openclaw:localOPENAI_API_KEY=$OPENAI_API_KEYOPENCLAW_EXTRA_MOUNTS=OPENCLAW_HOME_VOLUME=OPENCLAW_DOCKER_APT_PACKAGES=EOF
# 7. Add tmpfs to docker-compose.yml (required — see Known Issues)# Add to BOTH openclaw-gateway and openclaw-cli services:# tmpfs:# - /tmp:exec,size=512M
# 8. Start the gatewaydocker compose up -d openclaw-gateway
# 9. Wait ~15 seconds for startup, then get the dashboard URLsleep 15docker compose run --rm openclaw-cli dashboard --no-openThe dashboard URL will look like: http://127.0.0.1:18789/#token=<your-token>
Docker Compose Management
Section titled “Docker Compose Management”cd /tmp/openclaw-docker
# Stopdocker compose down
# Start again (no rebuild needed)docker compose up -d openclaw-gateway
# View logsdocker compose logs -f openclaw-gateway
# Check statusdocker compose run --rm openclaw-cli status
# Get dashboard URLdocker compose run --rm openclaw-cli dashboard --no-openKnown Issues and Fixes
Section titled “Known Issues and Fixes””no space left on device” when starting containers
Section titled “”no space left on device” when starting containers”Docker Desktop’s virtual disk may be full.
docker system df # check usagedocker system prune -f # remove stopped containers, unused networksdocker image prune -f # remove dangling images”Unable to create fallback OpenClaw temp dir: /tmp/openclaw-1000” (Compose only)
Section titled “”Unable to create fallback OpenClaw temp dir: /tmp/openclaw-1000” (Compose only)”The container can’t write to /tmp. Add a tmpfs mount to docker-compose.yml for both services:
services: openclaw-gateway: tmpfs: - /tmp:exec,size=512M openclaw-cli: tmpfs: - /tmp:exec,size=512MThis issue does not affect the Docker Sandbox approach.
Node version mismatch in community template images
Section titled “Node version mismatch in community template images”Some community-built sandbox templates (e.g. olegselajev241/openclaw-dmr:latest) ship Node 20, but OpenClaw requires Node >=22.12.0. Use our locally built openclaw:local image as the sandbox template instead, which includes Node 22.
Gateway takes ~15 seconds to respond after start
Section titled “Gateway takes ~15 seconds to respond after start”The Node.js gateway needs time to initialize. Wait 15 seconds before hitting http://127.0.0.1:18789/.
CLAUDE_AI_SESSION_KEY warnings (Compose only)
Section titled “CLAUDE_AI_SESSION_KEY warnings (Compose only)”These Docker Compose warnings are harmless and can be ignored:
level=warning msg="The \"CLAUDE_AI_SESSION_KEY\" variable is not set. Defaulting to a blank string."Configuration
Section titled “Configuration”Config file: ~/.openclaw/openclaw.json (JSON5 format)
Key settings:
gateway.auth.token— the auth token for the web UI and APIagents.defaults.model.primary— the AI model (useopenai/gpt-5.2or newer)env.OPENAI_API_KEY— references theOPENAI_API_KEYenv var (Compose approach)
API keys are stored in ~/.secrets and passed into containers via env vars.
Reference
Section titled “Reference”- OpenClaw Docker docs
- OpenClaw Configuration Reference
- Docker blog: Run OpenClaw Securely in Docker Sandboxes
- Docker Sandbox docs
- OpenAI Models — current models: gpt-5.2, gpt-5.2-chat-latest, gpt-5.2-pro