OpenClaw on Docker — the production-grade setup.
Docker is the cleanest way to run OpenClaw long-term. You get process isolation, easy updates, predictable storage, and a setup you can lift between machines without surprises. This is the stack we'd actually deploy in 2026 — and the gotchas we hit getting here.
Quick answers
How do I run OpenClaw in Docker?
Drop the officialdocker-compose.ymlin a directory, add your API key to.env, rundocker compose up -d, thendocker compose exec openclaw openclaw onboard. Five minutes from zero to running.What's the recommended OpenClaw Docker setup?
Pin a specific image tag (notlatest), mount./state:/root/.openclaw, setshm_size: 1gbfor the browser, bind ports to127.0.0.1only, and set memory + CPU limits.Does the browser work inside Docker?
Yes. Headless Chrome runs in the container with shm_size: 1gb and cap_add: SYS_ADMIN. For multiple concurrent browser sessions, use a sidecar pattern with browserless/chrome.How much RAM should I give the OpenClaw container?
4 GB minimum, 8 GB if you want browser automation, 16 GB for multi-agent setups. Set hard limits in compose so a runaway agent can't OOM your host.How do I update OpenClaw in Docker?
docker compose pullthendocker compose up -d. Pin versions in production. State survives because it's mounted in.
Architecture
Why Docker
Docker is the deployment most production OpenClaw setups settle on. You get isolation, easy updates, and portable state. Native installs are fine for laptops; Docker is fine everywhere else.
| Native install | Docker | |
|---|---|---|
| Skill isolation | host filesystem | container only |
| Updates | manual | compose pull |
| Portability | machine-specific | any Docker host |
| Browser support | host Chrome | headless inside |
| Multi-version | complex | trivial |
Before you start
Requirements
- Docker 24+ with Compose v2.
docker compose versionshould print 2.x or higher. - 4 GB RAM available to the container (8 GB if you want a browser).
- 20 GB free disk for the image, state directory, and growing memory files.
- An LLM API key. Stored in
.env, never baked into the image.
Copy-paste
The docker-compose.yml
The minimum viable Compose file. Drop into a fresh directory, create a .env alongside it, and you're running.
services:
openclaw:
image: openclaw/openclaw:latest
container_name: openclaw
restart: unless-stopped
ports:
- "127.0.0.1:18789:18789"
volumes:
- ./state:/root/.openclaw
- /etc/localtime:/etc/localtime:ro
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
- OPENCLAW_TZ=America/Los_Angeles
shm_size: "1gb"
cap_add:
- SYS_ADMIN
deploy:
resources:
limits:
memory: 4G
cpus: "2"
healthcheck:
test: ["CMD", "openclaw", "gateway", "status"]
interval: 30s
timeout: 5s
retries: 3
start_period: 30sANTHROPIC_API_KEY=sk-ant-api03-...Boot it:
docker compose up -d
docker compose exec openclaw openclaw onboardState
Volumes that matter
The single critical mount is ./state:/root/.openclaw. That folder contains every piece of state OpenClaw cares about: agent configs, memory, credentials, the SQLite memory index, channel session tokens. Lose it and you're starting over.
| Path inside container | What's there | Backup priority |
|---|---|---|
| ~/.openclaw/openclaw.json | Gateway config | High |
| ~/.openclaw/agents/ | Per-agent configs and workspaces | Critical |
| ~/.openclaw/memory/ | MEMORY.md, daily notes, SQLite index | Critical |
| ~/.openclaw/credentials/ | Channel tokens (Telegram, Slack, WhatsApp QR) | Critical |
| ~/.openclaw/skills/ | Installed skills | Medium — reinstallable |
| ~/.openclaw/cron/jobs.json | Scheduled jobs | High |
Backup pattern
tar -czf openclaw-state-$(date +%F).tar.gz state/ nightly via cron. The whole thing is a few hundred MB; storage is cheap.Tricky bit
Browser inside Docker
OpenClaw's browser tool needs Chromium. Two choices: bundle it in your image (simple, larger image), or run it as a sidecar service (smaller main image, more moving parts).
services:
openclaw:
image: openclaw/openclaw:latest
environment:
- OPENCLAW_BROWSER_CDP_URL=ws://browser:9222
depends_on:
- browser
browser:
image: browserless/chrome:latest
restart: unless-stopped
shm_size: "2gb"
environment:
- MAX_CONCURRENT_SESSIONS=4
- CONNECTION_TIMEOUT=300000shm_size matters
Without enough/dev/shm, Chrome crashes silently. Set 1 GB minimum, 2 GB for browser-heavy workloads.Day 2 ops
Updates and rollback
Pin versions in production. The latest tag is fine for development; production wants deterministic upgrades.
# Update
docker compose pull openclaw
docker compose up -d openclaw
docker image prune -f
# Rollback (assuming you tagged the previous version)
docker compose stop openclaw
sed -i 's|:2026.5.1|:2026.5.0|' docker-compose.yml
docker compose up -d openclawDon't OOM your host
Resource limits
An OpenClaw agent that gets stuck in a tool-call loop can easily eat all available memory. Always set hard limits.
deploy:
resources:
limits:
memory: 4G
cpus: "2"
reservations:
memory: 1GOn Linux, also set kernel-level OOM scoring so Docker kills its own runaway containers before the host kernel kills something more important:
echo 1000 > /proc/$(docker inspect -f '{{.State.Pid}}' openclaw)/oom_score_adjVisibility
Monitoring + logs
Docker logs are sufficient for development. For production, ship to your existing log stack:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "5"The most useful logs to watch:
incomplete turn detected: payloads=0— model returned nothing. Almost always a wrong base URL or bad API key.tool_result orphaned— session got into a bad state, often after compaction. Reset the session.heartbeat skipped— the agent's regular check-in didn't fire. Usually rate-limiting from the LLM provider.
Before you ship
Production checklist
- Pinned image version (no :latest in production)
- State volume backed up nightly
- Memory + CPU limits set
- Healthcheck configured
- Logs rotated or shipped
- Bound to 127.0.0.1 only (or behind a real auth layer)
- Sandbox mode set to
all - Day-1 security checklist completed
FAQ
Want OpenClaw without the ops?
Provision is the managed OpenClaw cloud — agents, channels, browser, and skills, all running. $99/mo. 48-hour free trial.