Guide
How to Deploy OpenClaw with Docker
Run OpenClaw in a Docker container on any server or local machine. This guide covers docker pull, docker-compose, bind-mount config, port mapping, health checks, and updating.
Prerequisites
- Docker installed (20.10+ recommended)
- 2 GB RAM minimum for the container (+ 3 GB swap recommended)
- An AI API key (OpenRouter, OpenAI, Anthropic, Google, etc.)
- A chat platform bot token (Telegram or Discord) — optional for web-only usage
Step 1: Pull the OpenClaw Image
docker pull ghcr.io/openclaw/openclaw:latestThe official image is hosted on GitHub Container Registry. Use the :latest tag for stable releases. Avoid :main for production — it's bleeding-edge and may contain bugs.
Step 2: Create the Config Directory
mkdir -p ~/openclaw/credentials
chmod 777 ~/openclaw
chmod 777 ~/openclaw/credentialsThe container runs as user node (uid 1000). The config directory needs open permissions since the host user and container user differ. The credentials/subdirectory is required for DM pairing to work.
Step 3: Create Your Config File
Create ~/openclaw/openclaw.json with your settings:
{
"gateway": {
"port": 18789,
"auth": { "token": "your-random-secret-token" }
},
"models": {
"providers": {
"openrouter": {
"apiKey": "sk-or-..."
}
}
},
"agents": {
"defaults": {
"model": {
"primary": "openrouter/anthropic/claude-sonnet-4.6"
}
}
},
"channels": {
"telegram": {
"enabled": true,
"botToken": "123456:ABC..."
}
},
"plugins": {
"entries": {
"telegram": { "enabled": true }
}
}
}See the OpenClaw Manual for the full config reference.
gateway.auth field must be an object with a token property — not a plain string. Both channels.telegram.enabled and plugins.entries.telegram.enabled must be true for Telegram to work.Step 4: Run the Container
docker run -d \
--name openclaw \
--restart unless-stopped \
--memory=2g --memory-swap=3g \
-v ~/openclaw:/home/node/.openclaw \
-p 18789:18789 \
ghcr.io/openclaw/openclaw:latest \
node openclaw.mjs gateway --allow-unconfiguredKey flags explained:
--memory=2g --memory-swap=3g— OpenClaw needs at least 2 GB RAM. 512 MB causes OOM crashes.-v ~/openclaw:/home/node/.openclaw— Bind-mounts your config directory into the container.-p 18789:18789— Exposes the web gateway port.--restart unless-stopped— Auto-restarts after crashes or reboots.
Step 5: Verify It's Running
docker logs openclaw --tail 20
curl http://localhost:18789Check the logs for any startup errors. The web gateway should respond at http://localhost:18789.
Using Docker Compose
For easier management, use a docker-compose.yml:
version: "3.8"
services:
openclaw:
image: ghcr.io/openclaw/openclaw:latest
container_name: openclaw
restart: unless-stopped
command: node openclaw.mjs gateway --allow-unconfigured
ports:
- "18789:18789"
volumes:
- ./openclaw:/home/node/.openclaw
deploy:
resources:
limits:
memory: 2gStart with docker compose up -d and stop with docker compose down.
Health Checks
Monitor your container with a health check endpoint:
curl -f http://localhost:18789 || echo "OpenClaw is down"For Docker Compose, add a healthcheck section:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:18789"]
interval: 30s
timeout: 10s
retries: 3Updating OpenClaw
docker pull ghcr.io/openclaw/openclaw:latest
docker stop openclaw && docker rm openclaw
# Re-run your docker run command from Step 4Your config is stored on the host via bind mount, so it persists across container recreations. With Docker Compose, just run docker compose pull && docker compose up -d.
Trusted Proxies
If running behind a reverse proxy (Nginx, Caddy, Traefik), configure trusted proxies in your config. OpenClaw only accepts exact IPs, not CIDR ranges:
"gateway": {
"trustedProxies": ["172.17.0.1"]
}Skip the Docker Setup
Don't want to manage Docker containers, config files, and updates yourself? OpenClaw Launch handles all of this automatically. Configure your AI bot visually and deploy in 30 seconds — no Docker knowledge needed.