Setup & Deployment
How to Run OpenClaw in Docker: The Complete Setup Guide (2026)
16 min read · Updated 2026-03-04
By DoneClaw Team · We run managed OpenClaw deployments and write from hands-on production experience.
Running OpenClaw in Docker gives you a fully isolated, reproducible AI agent environment that you can spin up in minutes, tear down without a trace, and deploy identically across any machine. Whether you're trying OpenClaw for the first time on your laptop, deploying it to a VPS, or building a production setup with agent sandboxing — Docker is the cleanest path. This guide covers everything: from the one-command quick start to advanced multi-container architectures with Ollama, sandbox isolation, automated updates, and the troubleshooting fixes that will save you hours of debugging.
Why Run OpenClaw in Docker?
Before diving into commands, let's be clear about when Docker makes sense — and when it doesn't.
Docker Is Right for You If:
Skip Docker If:
- **You want isolation.** OpenClaw runs code, browses the web, and executes shell commands. Docker contains all of that inside a boundary you control.
- **You're deploying to a VPS.** Docker standardizes the environment so your Hetzner box, DigitalOcean droplet, or AWS instance all run the same image.
- **You want reproducibility.** Pin an image tag, and you'll get the exact same OpenClaw version months later.
- **You run multiple services.** Docker Compose makes it trivial to run OpenClaw alongside Ollama, Traefik, monitoring tools, or databases.
- **You value clean uninstalls.** Remove the containers and volumes, and OpenClaw is gone. No leftover global packages.
- You're developing on your own machine and want the fastest iteration loop — the native install is simpler.
- You're on a Raspberry Pi with limited RAM (under 2 GB) — the Docker build itself may OOM. See our Raspberry Pi guide for the direct install approach.
Prerequisites
Before starting, make sure you have:
Requirement: Docker Engine / Desktop, Minimum: v24+, Recommended: v27+
Requirement: Docker Compose, Minimum: v2.20+, Recommended: v2.30+
Requirement: RAM (for build), Minimum: 2 GB, Recommended: 4 GB
Requirement: RAM (for runtime), Minimum: 1 GB, Recommended: 2 GB
Requirement: Disk space, Minimum: 3 GB, Recommended: 5 GB
Requirement: OS, Minimum: Linux, macOS, Windows (WSL2), Recommended: Ubuntu 22.04+
Check your versions:
If you're on a VPS, make sure you're not running as a non-Docker user. You'll need `docker` group membership or root access:
docker --version
docker compose version
sudo usermod -aG docker $USER
# Log out and back in for this to take effectQuick Start: One Command Setup
OpenClaw's Docker setup is designed around a single script that handles everything:
That's it. The script will:
1. **Build the Docker image** locally from the Dockerfile (or pull a remote image if configured) 2. **Run the onboarding wizard** — asks about model provider, messaging channels, and configuration 3. **Generate a gateway token** and write it to `.env` 4. **Start the gateway** via Docker Compose 5. **Print the dashboard URL** so you can access the web UI
After completion, open `http://127.0.0.1:18789/` in your browser and paste the generated token into Settings.
What Gets Created on Your Host
The setup creates two directories that persist outside Docker:
These are bind-mounted into the container, so your data survives container restarts and rebuilds.
git clone https://github.com/openclaw/openclaw.git
cd openclaw
./docker-setup.sh
~/.openclaw/ # Configuration, API keys, agent memory
~/.openclaw/workspace/ # Agent workspace — files the agent creates live hereUnderstanding the Docker Compose Architecture
OpenClaw's `docker-compose.yml` defines two services:
1. `openclaw-gateway` — The Main Service
This is the OpenClaw brain. It runs the gateway server, handles messaging channels (Telegram, Discord, WhatsApp), manages agent sessions, and exposes the web dashboard.
Key details:
2. `openclaw-cli` — The Management Tool
This is a helper container for running CLI commands against the gateway:
Notice the security hardening: `cap_drop` removes network capabilities, and `no-new-privileges` prevents privilege escalation. The `network_mode: "service:openclaw-gateway"` shares the gateway's network namespace so the CLI can reach `127.0.0.1:18789`.
Use it like this:
- **Port 18789**: Web dashboard and API
- **Port 18790**: Bridge port for node pairing (phone, other devices)
- **`init: true`**: Ensures proper signal handling and zombie process cleanup
- **`restart: unless-stopped`**: Auto-restart on crashes, but not after manual `docker compose stop`
- **Health check**: Polls `/healthz` every 30 seconds — integrates with Docker's health monitoring
services:
openclaw-gateway:
image: ${OPENCLAW_IMAGE:-openclaw:local}
environment:
HOME: /home/node
TERM: xterm-256color
OPENCLAW_GATEWAY_TOKEN: ${OPENCLAW_GATEWAY_TOKEN}
volumes:
- ${OPENCLAW_CONFIG_DIR}:/home/node/.openclaw
- ${OPENCLAW_WORKSPACE_DIR}:/home/node/.openclaw/workspace
ports:
- "${OPENCLAW_GATEWAY_PORT:-18789}:18789"
- "${OPENCLAW_BRIDGE_PORT:-18790}:18790"
init: true
restart: unless-stopped
healthcheck:
test: ["CMD", "node", "-e",
"fetch('http://127.0.0.1:18789/healthz').then((r)=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
interval: 30s
timeout: 5s
retries: 5
start_period: 20s
openclaw-cli:
image: ${OPENCLAW_IMAGE:-openclaw:local}
network_mode: "service:openclaw-gateway"
cap_drop:
- NET_RAW
- NET_ADMIN
security_opt:
- no-new-privileges:true
volumes:
- ${OPENCLAW_CONFIG_DIR}:/home/node/.openclaw
- ${OPENCLAW_WORKSPACE_DIR}:/home/node/.openclaw/workspace
stdin_open: true
tty: true
init: true
entrypoint: ["node", "dist/index.js"]
depends_on:
- openclaw-gateway
# Check gateway status
docker compose run --rm openclaw-cli gateway probe
# List connected devices
docker compose run --rm openclaw-cli devices list
# Approve a pairing request
docker compose run --rm openclaw-cli pairing approve telegram <CODE>
# Open the dashboard
docker compose run --rm openclaw-cli dashboard --no-openUsing Pre-Built Images (Skip the Build)
Building from source takes 3-8 minutes depending on your machine. If you want to skip that, use the official pre-built images from GitHub Container Registry:
Available tags:
Tag: `latest`, Description: Latest stable release
Tag: `main`, Description: Latest build from main branch (bleeding edge)
Tag: `2026.2.26`, Description: Specific version pin
For production, always pin a specific version:
The base image is `node:22-bookworm` with OCI annotations for traceability.
export OPENCLAW_IMAGE="ghcr.io/openclaw/openclaw:latest"
./docker-setup.sh
export OPENCLAW_IMAGE="ghcr.io/openclaw/openclaw:2026.2.26"
./docker-setup.shEnabling Agent Sandboxing
By default, OpenClaw's agent can execute shell commands inside the gateway container. For stronger isolation, enable **sandbox mode** — this creates a separate Docker container for each agent session's tool execution.
This does several things: 1. Installs Docker CLI inside the OpenClaw image 2. Mounts the Docker socket into the gateway container 3. Configures `agents.defaults.sandbox.mode` in OpenClaw's settings 4. Builds the sandbox image (`openclaw-sandbox:bookworm-slim`)
Rootless Docker Socket
If you're running rootless Docker (recommended for security), specify the socket path:
Security Implications
Mounting `docker.sock` gives the container access to the Docker daemon — essentially root on the host. This is a deliberate tradeoff: sandbox isolation for agent tools, at the cost of Docker daemon access from the gateway container.
For a deeper dive on securing this setup, see our security hardening guide.
export OPENCLAW_SANDBOX=1
./docker-setup.sh
export OPENCLAW_SANDBOX=1
export OPENCLAW_DOCKER_SOCKET=/run/user/1000/docker.sock
./docker-setup.shAdvanced: OpenClaw + Ollama (Multi-Container Setup)
One of the most popular Docker setups pairs OpenClaw with Ollama for local model inference. This gives you a completely self-hosted AI agent stack with zero API costs.
Create a `docker-compose.override.yml` in your OpenClaw repo root:
Then start everything together:
Docker Compose automatically merges `docker-compose.yml` and `docker-compose.override.yml`.
Configure OpenClaw to Use Ollama
Once Ollama is running, pull a model and configure OpenClaw:
In OpenClaw's configuration, set the Ollama endpoint. Since both containers are on the same Docker network, use the service name:
Resource Planning for Multi-Container
Setup: OpenClaw only, RAM Required: 1-2 GB, Disk Required: 2-3 GB
Setup: OpenClaw + Ollama (7B model), RAM Required: 6-8 GB, Disk Required: 8-10 GB
Setup: OpenClaw + Ollama (13B model), RAM Required: 12-16 GB, Disk Required: 15-20 GB
Setup: OpenClaw + Ollama + Sandbox, RAM Required: +1 GB per active session, Disk Required: +500 MB
For the best model choices with Ollama, see our dedicated comparison guide.
services:
ollama:
image: ollama/ollama:latest
volumes:
- ollama_data:/root/.ollama
ports:
- "11434:11434"
restart: unless-stopped
# Uncomment for GPU passthrough:
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: all
# capabilities: [gpu]
volumes:
ollama_data:
docker compose up -d
# Pull a model
docker compose exec ollama ollama pull llama3.2
# Verify it's working
docker compose exec ollama ollama list
Model provider: ollama
Ollama URL: http://ollama:11434Skip 60 minutes of setup — deploy in 60 seconds
DoneClaw handles Docker, servers, security, and updates. Your OpenClaw agent is ready to chat in under a minute.
Deploy NowEnvironment Variables Reference
The Docker setup uses `.env` for configuration. Here's a complete reference:
Variable: `OPENCLAW_IMAGE`, Default: `openclaw:local`, Description: Docker image to use
Variable: `OPENCLAW_GATEWAY_TOKEN`, Default: (generated), Description: Authentication token for dashboard/API
Variable: `OPENCLAW_GATEWAY_PORT`, Default: `18789`, Description: Host port for web dashboard
Variable: `OPENCLAW_BRIDGE_PORT`, Default: `18790`, Description: Host port for device bridge
Variable: `OPENCLAW_GATEWAY_BIND`, Default: `lan`, Description: Bind mode: `lan`, `loopback`, or specific IP
Variable: `OPENCLAW_CONFIG_DIR`, Default: `~/.openclaw`, Description: Host path for config
Variable: `OPENCLAW_WORKSPACE_DIR`, Default: `~/.openclaw/workspace`, Description: Host path for workspace
Variable: `OPENCLAW_SANDBOX`, Default: (unset), Description: Enable sandbox: `1`, `true`, `yes`, `on`
Variable: `OPENCLAW_DOCKER_SOCKET`, Default: `/var/run/docker.sock`, Description: Docker socket path
Variable: `OPENCLAW_EXTRA_MOUNTS`, Default: (unset), Description: Comma-separated extra bind mounts
Variable: `OPENCLAW_HOME_VOLUME`, Default: (unset), Description: Named volume for `/home/node`
Variable: `OPENCLAW_DOCKER_APT_PACKAGES`, Default: (unset), Description: Extra apt packages for build
Variable: `OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT`, Default: (Chromium default), Description: Limit browser renderer processes
Bind Mode Explained
The `OPENCLAW_GATEWAY_BIND` setting controls network exposure:
- **`loopback`**: Only accessible from `127.0.0.1` — safest for local development
- **`lan`**: Accessible from your local network — needed for Tailscale or LAN access
- **Warning**: Docker's port mapping can bypass `loopback` binding on some systems. Always use firewall rules (`ufw`, `iptables`) as a second layer. See our Tailscale setup guide for zero-trust networking.
Extra Host Mounts
Need to give OpenClaw access to files outside the workspace? Use `OPENCLAW_EXTRA_MOUNTS`:
This generates a `docker-compose.extra.yml` that's automatically included. Each mount follows Docker's `source:target[:options]` format.
Common mounts:
export OPENCLAW_EXTRA_MOUNTS="$HOME/projects:/home/node/projects:ro,$HOME/.ssh:/home/node/.ssh:ro"
./docker-setup.sh
# Read-only access to your code repositories
$HOME/github:/home/node/github:ro
# SSH keys for git operations (read-only!)
$HOME/.ssh:/home/node/.ssh:ro
# Shared downloads folder
$HOME/Downloads:/home/node/Downloads:rwClawDock Shell Helpers
For day-to-day management, install the official shell helpers:
Available commands:
Command: `clawdock-start`, Description: Start the gateway
Command: `clawdock-stop`, Description: Stop the gateway
Command: `clawdock-restart`, Description: Restart the gateway
Command: `clawdock-dashboard`, Description: Print dashboard URL
Command: `clawdock-logs`, Description: Tail gateway logs
Command: `clawdock-status`, Description: Show container health
Command: `clawdock-update`, Description: Pull latest image and restart
Command: `clawdock-help`, Description: Show all available commands
mkdir -p ~/.clawdock && curl -sL \
https://raw.githubusercontent.com/openclaw/openclaw/main/scripts/shell-helpers/clawdock-helpers.sh \
-o ~/.clawdock/clawdock-helpers.sh
# Add to your shell (zsh example)
echo 'source ~/.clawdock/clawdock-helpers.sh' >> ~/.zshrc
source ~/.zshrcCI/CD and Automation
For headless environments (CI pipelines, cron jobs, automated deployments), disable TTY allocation:
The `-T` flag prevents Docker Compose from allocating a pseudo-TTY, which causes issues in non-interactive environments.
Automated Health Monitoring
Combine Docker's built-in health check with external monitoring:
docker compose run -T --rm openclaw-cli gateway probe
docker compose run -T --rm openclaw-cli devices list --json
#!/bin/bash
# health-check.sh — run via cron every 5 minutes
HEALTH=$(docker inspect --format='{{.State.Health.Status}}' openclaw-openclaw-gateway-1)
if [ "$HEALTH" != "healthy" ]; then
echo "OpenClaw unhealthy: $HEALTH" | mail -s "OpenClaw Alert" [email protected]
docker compose restart openclaw-gateway
fiUpdating OpenClaw in Docker
With Pre-Built Images
With Local Builds
Zero-Downtime Considerations
OpenClaw maintains persistent connections (WebSocket for Telegram, etc.), so restarts will briefly disconnect your messaging channels. They reconnect automatically within 10-30 seconds. For cron jobs and heartbeats, pending tasks resume after restart.
# Pull the latest image
docker compose pull openclaw-gateway
# Restart with the new image
docker compose up -d openclaw-gateway
# Pull latest source
git pull origin main
# Rebuild the image
docker compose build openclaw-gateway
# Restart
docker compose up -d openclaw-gatewayTroubleshooting Common Docker Issues
Exit Code 137 (OOM Killed)
**Symptom**: Container exits during build or startup with code 137.
**Cause**: Not enough RAM. The build phase (`pnpm install`) is memory-hungry.
**Fix**:
Or skip the build entirely with a pre-built image.
"Unauthorized" or "Disconnected (1008): Pairing Required"
**Symptom**: Dashboard shows disconnected or unauthorized errors.
**Fix**:
Port 18789 Already in Use
**Symptom**: `bind: address already in use`
**Fix**:
Container Can't Reach Ollama
**Symptom**: Connection refused when accessing Ollama from OpenClaw.
**Fix**: Make sure both services are on the same Docker network. If you're using `docker-compose.override.yml`, Docker Compose handles this automatically. If running Ollama separately:
Docker Socket Permission Denied (Sandbox Mode)
**Symptom**: `permission denied while trying to connect to the Docker daemon socket`
**Fix**:
Build Takes Too Long
**Symptom**: Local build takes 10+ minutes.
**Fix**: Use a pre-built image:
This reduces setup from minutes to seconds (just a `docker pull`).
# Check available memory
free -h
# For Docker Desktop, increase memory in Settings → Resources
# Minimum: 2 GB for build, 4 GB recommended
# On a VPS, add swap as a safety net:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
# Get a fresh dashboard URL with token
docker compose run --rm openclaw-cli dashboard --no-open
# If that doesn't work, list and approve devices
docker compose run --rm openclaw-cli devices list
docker compose run --rm openclaw-cli devices approve <requestId>
# Find what's using the port
sudo lsof -i :18789
# Option 1: Kill the conflicting process
# Option 2: Change the port in .env
echo "OPENCLAW_GATEWAY_PORT=18800" >> .env
docker compose up -d
# Create a shared network
docker network create openclaw-net
# Run Ollama on that network
docker run -d --name ollama --network openclaw-net ollama/ollama
# Add the network to OpenClaw's compose
# In docker-compose.override.yml:
# services:
# openclaw-gateway:
# networks:
# - openclaw-net
# networks:
# openclaw-net:
# external: true
# Check the Docker socket GID on your host
stat -c '%g' /var/run/docker.sock
# Set it in your .env or docker-compose
# group_add:
# - "998" # Replace with your actual Docker GID
export OPENCLAW_IMAGE="ghcr.io/openclaw/openclaw:latest"
./docker-setup.shProduction Hardening Checklist
If you're running OpenClaw Docker in production (on a VPS or always-on server), follow this checklist:
Log Rotation
Docker logs can grow unbounded. Add to your `docker-compose.override.yml`:
Reverse Proxy with Caddy
A minimal Caddy setup for HTTPS:
Add Caddy to your compose stack or run it separately. This gives you automatic HTTPS via Let's Encrypt.
- **Use `loopback` bind mode** unless you specifically need LAN access
- **Set up a reverse proxy** (Nginx, Caddy, Traefik) with HTTPS
- **Configure firewall rules** — Docker can bypass `ufw`; use `DOCKER-USER` chain
- **Pin a specific image version** instead of `latest`
- **Enable sandbox mode** for untrusted agent operations
- **Set up log rotation** to prevent disk fill
- **Monitor container health** with the built-in healthcheck
- **Use Tailscale** for zero-trust remote access
- **Back up** `~/.openclaw/` regularly — this contains your agent's memory and config
- **Review the full** security hardening guide
services:
openclaw-gateway:
logging:
driver: "json-file"
options:
max-size: "50m"
max-file: "3"
openclaw.yourdomain.com {
reverse_proxy localhost:18789
}Docker vs Native Install: When to Choose What
Factor: Setup time, Docker: 5-10 min, Native Install: 3-5 min
Factor: Isolation, Docker: Full container isolation, Native Install: Runs on host directly
Factor: Updates, Docker: Pull new image, restart, Native Install: `git pull`, rebuild
Factor: Resource overhead, Docker: ~100-200 MB extra, Native Install: None
Factor: Cleanup, Docker: Remove containers + volumes, Native Install: Manual uninstall
Factor: Multi-service, Docker: Docker Compose makes it easy, Native Install: Manual process management
Factor: Best for, Docker: VPS, production, multi-service, Native Install: Development, Raspberry Pi
For most users deploying on a VPS or wanting a clean setup, Docker is the recommended path. For development or resource-constrained devices, go native. Our complete deployment guide covers both approaches in detail.
Conclusion
Running OpenClaw in Docker is the cleanest way to deploy a personal AI agent — you get isolation, reproducibility, and easy multi-service composition out of the box. The `docker-setup.sh` script handles 90% of the work, and the Docker Compose architecture gives you a solid foundation to build on. Start with the quick setup, connect your preferred messaging channel, and you'll have a fully functional AI agent running in minutes. From there, layer on Ollama for local models, enable sandboxing for security, and add monitoring for production reliability. The Docker ecosystem around OpenClaw is maturing fast — between ClawDock helpers, pre-built GHCR images, and the growing community of Docker-first deployments, containerized OpenClaw is becoming the default for serious users.
Skip the setup? DoneClaw deploys OpenClaw for you — $29/mo with 7-day free trial, zero configuration.
Skip 60 minutes of setup — deploy in 60 seconds
DoneClaw handles Docker, servers, security, and updates. Your OpenClaw agent is ready to chat in under a minute.
Deploy NowFrequently asked questions
Can I run OpenClaw Docker on a 1 GB VPS?
Technically, the runtime only needs about 1 GB of RAM. But the **build** phase requires at least 2 GB. The workaround: use a pre-built image (`OPENCLAW_IMAGE="ghcr.io/openclaw/openclaw:latest"`) to skip the build entirely. With a pre-built image, a 1 GB VPS works for light usage, though 2 GB is recommended for comfortable operation. See our cheap VPS hosting guide for specific provider recommendations.
Does OpenClaw Docker work on ARM (Apple Silicon, Raspberry Pi)?
Yes. The official images support both `amd64` and `arm64` architectures. On Apple Silicon Macs, Docker Desktop handles this natively. On Raspberry Pi 4/5, you'll need at least 4 GB RAM for the Docker build. If you have a 2 GB Pi, use the native install instead — see our Raspberry Pi guide.
How do I connect Telegram/Discord/WhatsApp to the Docker setup?
The messaging channel setup works identically to native installs — the onboarding wizard handles it during `docker-setup.sh`. For Telegram specifically, you'll create a bot via @BotFather, provide the token during onboarding, then approve the pairing: ```bash docker compose run --rm openclaw-cli pairing approve telegram <CODE> ``` See our dedicated guides for Telegram, Discord, and WhatsApp.
How do I back up my OpenClaw Docker instance?
Back up the two host directories: ```bash tar czf openclaw-backup-$(date +%Y%m%d).tar.gz ~/.openclaw/ ``` This captures all configuration, API keys, agent memory, and workspace files. The Docker image itself doesn't need backing up — it's reproducible from the source or registry.
Can I run multiple OpenClaw instances on the same host?
Yes. Clone the repo to different directories and change the port mappings in `.env`: ```bash # Instance 1 (default ports) OPENCLAW_GATEWAY_PORT=18789 OPENCLAW_BRIDGE_PORT=18790 # Instance 2 OPENCLAW_GATEWAY_PORT=18791 OPENCLAW_BRIDGE_PORT=18792 ``` Also change `OPENCLAW_CONFIG_DIR` and `OPENCLAW_WORKSPACE_DIR` so each instance has its own data.