On this page
π€ Why Docker?
| Benefit | Details |
|---|---|
| Isolation | OpenClaw runs in its own container β doesn't touch your host Node.js, npm, or system libraries |
| Reproducibility | Same image, same behavior everywhere β local dev, staging, production VPS |
| Easy updates | docker pull + restart β no npm conflicts, no dependency issues |
| Security | Container boundary limits blast radius if the agent is compromised |
| VPS-friendly | Most VPS providers (Hostinger, Hetzner, DigitalOcean) have Docker pre-installed or one-click templates |
π Prerequisites
- Docker Engine 24+ β check with
docker --version - Docker Compose v2+ β check with
docker compose version - 2 GB RAM minimum (4 GB recommended)
- 10 GB disk space for images, volumes, and logs
- AI API key β Anthropic, OpenAI, OpenRouter, or Google Gemini
Install Docker (if needed)
# Ubuntu / Debian
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# Log out and back in for group change
# Verify
docker run hello-world
β‘ Quick start
Fastest way to get running β a single command using the official image:
docker run -d --name openclaw \
--restart unless-stopped \
-v openclaw-config:/home/node/.openclaw \
-v openclaw-workspace:/home/node/.openclaw/workspace \
-p 127.0.0.1:18789:18789 \
-e HOME=/home/node \
ghcr.io/openclaw/openclaw:latest \
node dist/index.js gateway --port 18789
This starts the gateway on port 18789, bound to localhost only (secure by default). Config and workspace persist in named Docker volumes.
127.0.0.1: prefix. Without it, Docker binds to 0.0.0.0 β exposing the Control UI to the internet. See the Security Guide for why this matters.π Docker Compose setup (recommended)
For production deployments, use a docker-compose.yml file for easier management:
# docker-compose.yml
services:
openclaw:
image: ghcr.io/openclaw/openclaw:latest
container_name: openclaw
restart: unless-stopped
env_file: .env
environment:
- HOME=/home/node
- NODE_ENV=production
- TERM=xterm-256color
volumes:
- ./config:/home/node/.openclaw
- ./workspace:/home/node/.openclaw/workspace
ports:
- "127.0.0.1:18789:18789"
command: >
node dist/index.js gateway
--bind 0.0.0.0
--port 18789
--allow-unconfigured
Start it
# Start in background
docker compose up -d
# View logs
docker compose logs -f openclaw
# Stop
docker compose down
# Restart after config change
docker compose restart openclaw
π Environment variables
Create a .env file alongside your docker-compose.yml:
# .env
OPENCLAW_GATEWAY_PORT=18789
OPENCLAW_GATEWAY_BIND=0.0.0.0
OPENCLAW_GATEWAY_TOKEN=your-strong-random-token-here
# AI Provider (pick one)
ANTHROPIC_API_KEY=sk-ant-...
# OPENAI_API_KEY=sk-...
# OPENROUTER_API_KEY=sk-or-...
# GOOGLE_API_KEY=AIza...
.env to version control. Add it to .gitignore. Generate a strong gateway token: openssl rand -hex 32Key variables
| Variable | Purpose | Default |
|---|---|---|
OPENCLAW_GATEWAY_TOKEN | Auth token for Control UI access | Generated on first run |
OPENCLAW_GATEWAY_PORT | Gateway port | 18789 |
OPENCLAW_GATEWAY_BIND | Bind address inside container | 0.0.0.0 (use port mapping for security) |
ANTHROPIC_API_KEY | Anthropic Claude API key | β |
NODE_ENV | production for VPS deployment | development |
πΎ Persistent volumes
Your agent's config, workspace files, credentials, and cron jobs all live on disk. Docker volumes ensure they survive container restarts and image updates.
| Host path | Container path | Contents |
|---|---|---|
./config | /home/node/.openclaw | openclaw.json, credentials, cron jobs, state |
./workspace | /home/node/.openclaw/workspace | SOUL.md, AGENTS.md, USER.md, MEMORY.md, daily logs |
./config and ./workspace directories regularly. They contain everything needed to rebuild your agent from scratch. A simple rsync or tar cron job is enough.π§ Onboarding inside Docker
Run the interactive setup wizard inside the container:
# Interactive onboarding
docker compose exec openclaw \
node dist/index.js onboard --install-daemon
# Or non-interactive (for automation)
docker compose exec openclaw \
node dist/index.js onboard --non-interactive \
--auth-choice anthropic-api-key \
--model "anthropic/claude-sonnet-4-5"
The wizard creates openclaw.json, sets up your AI provider, and optionally configures your first channel.
π Accessing the Control UI
Local machine
If Docker runs on your local machine, open http://localhost:18789 and enter your gateway token.
Remote VPS
If Docker runs on a VPS, use an SSH tunnel β never expose port 18789 publicly:
# From your local machine
ssh -L 18789:localhost:18789 user@your-vps-ip
# Then open http://localhost:18789 in your browser
For persistent remote access, consider Tailscale β bind to your Tailscale IP instead of localhost.
π Updating OpenClaw
# Pull latest image
docker compose pull
# Recreate container with new image
docker compose up -d
# Verify version
docker compose exec openclaw node dist/index.js --version
Your config and workspace volumes are untouched during updates β only the application code changes. This is one of Docker's biggest advantages over native installs.
π‘ Pin to a specific version for production stability:
image: ghcr.io/openclaw/openclaw:2026.3.23
Then update deliberately by changing the tag, not with :latest.
π Tool sandboxing with Docker
OpenClaw supports running tool execution inside nested Docker containers β βDocker-in-Dockerβ style sandboxing. This means the gateway runs in one container and spawns child containers for untrusted tool calls.
# Enable in openclaw.json
{
"agents": {
"defaults": {
"sandbox": {
"mode": "non-main",
"scope": "session",
"workspaceAccess": "none"
}
}
}
}
For this to work, mount the Docker socket into the OpenClaw container:
# Add to docker-compose.yml volumes
volumes:
- ./config:/home/node/.openclaw
- ./workspace:/home/node/.openclaw/workspace
- /var/run/docker.sock:/var/run/docker.sock
π§ Troubleshooting
| Problem | Fix |
|---|---|
| Container won't start | docker compose logs openclaw β check for missing env vars or port conflicts |
| Port already in use | lsof -i :18789 on host β kill the conflicting process or change the port |
| Can't access Control UI | Check port mapping includes 127.0.0.1: prefix. Use SSH tunnel for remote. |
| Config changes not applied | docker compose restart openclaw β gateway needs restart after config edits |
| WhatsApp QR not showing | docker compose exec -it openclaw node dist/index.js channels login |
| Permission denied on volumes | Check ownership: chown -R 1000:1000 ./config ./workspace (node user inside container) |
| Out of disk space | docker system prune -af to clean old images/containers |
| Container keeps restarting | docker compose logs --tail 50 openclaw β usually a missing API key or bad config |
Useful commands
# Shell into the container
docker compose exec -it openclaw bash
# Run doctor inside container
docker compose exec openclaw node dist/index.js doctor --deep --yes
# Check resource usage
docker stats openclaw
# View container details
docker inspect openclaw | grep -A5 "Mounts"
π What's next
| Action | Guide |
|---|---|
| Secure your deployment | Security & DM Policies |
| Connect messaging channels | Channels Overview |
| Configure your agent's personality | SOUL.md & Identity |
| Set up scheduled automations | Automation & Cron |
| Deploy to a VPS | VPS Deploy Guide |