OpenClaw Docker: Complete Setup & Compose Guide
- Docker provides isolation, easy updates, and multi-instance support — making it the recommended way to run OpenClaw in production
- A minimal setup requires only docker-compose.yml and a .env file with your API key; volumes persist data across container restarts and updates
- Run multiple agents simultaneously with different models (e.g., Haiku for speed, Sonnet for depth) by defining multiple services in one Compose file
- Updating OpenClaw is a two-step process: docker compose pull, then docker compose up -d --force-recreate — no data is lost
- Always set CPU and memory limits, configure health checks, and place Nginx with SSL in front of the web UI for production deployments
- Use Portainer for a browser-based monitoring dashboard, or docker compose logs -f for real-time log tailing
- Choose bare-metal over Docker only on very resource-constrained servers (under 512MB RAM) where container overhead is a concern
Docker is the recommended way to install OpenClaw — it isolates the agent in a container, simplifies updates to a single docker pull command, and lets you run multiple instances on one server without conflicts. The entire setup takes under 10 minutes if Docker is already installed.
Why Docker Is the Best Way to Run OpenClaw
If you have ever installed a complex AI tool directly on a server and later struggled to update it, roll it back, or run two versions at once — Docker is the answer you have been looking for. OpenClaw is a multi-process application: it runs one or more agent processes, manages API credentials, writes logs, and optionally exposes a web UI. All of that is much cleaner inside a container.
Three reasons Docker makes OpenClaw easier:
Isolation. Everything OpenClaw needs — Node.js runtime, environment variables, file paths — lives inside the container. Your host system stays clean. You can remove OpenClaw entirely with a singledocker compose down -v command, with zero leftover files.
Easy updates. Upgrading OpenClaw means pulling a new image and recreating the container. You do not touch your host Python or Node versions. Rollback is equally simple: just pin the previous image tag.
Multi-instance. Want to run one agent on Claude claude-sonnet-4-6 for fast tasks and another on Claude Opus for deep research? Docker Compose makes it trivial to spin up two isolated containers with different environment variables, different ports, and different volume mounts — all from one YAML file.
---
Prerequisites
Before starting, make sure the following are installed on your server or workstation:
- Docker Engine 24+ (or Docker Desktop on macOS/Windows)
- Docker Compose v2 (included with Docker Desktop; on Linux install the
docker-compose-pluginpackage) - An Anthropic API key (or another supported provider key)
- Basic familiarity with the terminal
docker --version # Docker version 24.x or higher docker compose version # Docker Compose version v2.x
---
Step-by-Step: docker-compose.yml
Create a working directory and add the following files:
mkdir openclaw && cd openclaw
1. docker-compose.yml
version: "3.9"services: openclaw: image: openclaw/agent:latest container_name: openclaw_main restart: unless-stopped env_file: - .env ports: - "3000:3000" # Web UI volumes: - ./data:/app/data # Persistent agent data - ./logs:/app/logs # Log files - ./config:/app/config # Custom config overrides healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/health"] interval: 30s timeout: 10s retries: 3 start_period: 20s deploy: resources: limits: cpus: "1.0" memory: 512M
2. .env file
Create a .env file in the same directory. Never commit this file to git.
# API credentials ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxxAgent settings
OCL_MODEL=claude-sonnet-4-6 OCL_MAX_TOKENS=4096 OCL_LOG_LEVEL=infoWeb UI
OCL_UI_PORT=3000 OCL_UI_SECRET=change-this-to-a-random-stringTelegram notifications (optional)
TELEGRAM_BOT_TOKEN= TELEGRAM_CHAT_ID=
3. Create volume directories
mkdir -p data logs config
Now start the container:
docker compose up -d
Check that it is running:
docker compose ps docker compose logs -f openclaw
---
Configuration: Ports, Variables, and Secrets
Ports. The left side of"3000:3000" is the host port. If port 3000 is already taken on your server, change it to "8080:3000" and access the UI at http://your-server:8080.
Environment variables. All OpenClaw settings can be passed through the .env file. The key ones:
| Variable | Description | Default |
|---|---|---|
ANTHROPIC_API_KEY | Your Anthropic API key | Required |
OCL_MODEL | Model to use | claude-sonnet-4-6 |
OCL_MAX_TOKENS | Max response tokens | 4096 |
OCL_LOG_LEVEL | debug, info, warn, error | info |
OCL_UI_SECRET | Password for web UI | Required |
.env files. Use Docker secrets or a secrets manager like HashiCorp Vault. At minimum, restrict .env permissions:
chmod 600 .env
If you are on a shared server, consider using Docker Secrets syntax in the compose file and storing the actual values in /run/secrets/.
---
Running Multiple Agents with Different Models
One of Docker Compose's biggest advantages is running several agent instances side-by-side. Here is how to set up a "fast" agent (Haiku for cheap tasks) and a "deep" agent (Sonnet for complex research):
version: "3.9"services: agent-fast: image: openclaw/agent:latest container_name: openclaw_fast restart: unless-stopped env_file: .env.fast ports: - "3001:3000" volumes: - ./data/fast:/app/data - ./logs/fast:/app/logs
agent-deep: image: openclaw/agent:latest container_name: openclaw_deep restart: unless-stopped env_file: .env.deep ports: - "3002:3000" volumes: - ./data/deep:/app/data - ./logs/deep:/app/logs
Create .env.fast with OCL_MODEL=claude-haiku-4-5 and .env.deep with OCL_MODEL=claude-sonnet-4-6. Each agent runs on its own port, with its own data directory.
---
Updating OpenClaw
Updating is a two-step process:
# Pull the latest image docker compose pullRecreate the container with the new image
docker compose up -d --force-recreate
Your data persists because it lives in the ./data volume on the host, not inside the container. The old image is cached locally until you clean it up:
docker image prune -f
image: openclaw/agent:1.4.2
This way updates only happen when you explicitly change the tag.
---
Monitoring: Portainer and Docker Logs
Docker logs are the simplest option:# Follow live logs docker compose logs -f openclawLast 100 lines
docker compose logs --tail=100 openclawLogs from a specific time
docker compose logs --since 1h openclaw
portainer:
image: portainer/portainer-ce:latest
container_name: portainer
restart: unless-stopped
ports:
- "9000:9000"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
volumes: portainer_data:
Access Portainer at http://your-server:9000. You can view logs, restart containers, inspect environment variables, and check resource usage — all from a browser.
---
Troubleshooting Common Docker Issues
Container exits immediately. Check logs:docker compose logs openclaw. Usually this is a missing or malformed environment variable. Verify your .env file has no extra spaces around = signs.
Port already in use. Change the host port in docker-compose.yml, e.g., "3001:3000" instead of "3000:3000".
Permission denied on volume. The container process may not have write access to your mounted directories. Fix with:
chown -R 1000:1000 ./data ./logs
docker compose exec openclaw env | grep ANTHROPIC
start_period in the healthcheck block.
Out of memory. If the agent is being OOM-killed, increase the memory limit in deploy.resources.limits.memory or add swap to your host.
---
Docker vs Bare-Metal: When to Use Which
| Scenario | Docker | Bare-Metal |
|---|---|---|
| Quick evaluation | Fast setup | More steps |
| Production server | Recommended | Fine if experienced |
| Multiple instances | Easy | Complex |
| Custom Node.js version needed | No conflict | Risk of conflicts |
| Team environment | Consistent | Varies by machine |
| Resource-constrained VPS (512MB RAM) | Slight overhead | Leaner |
---
Production Tips
Resource limits. Always set CPU and memory limits so a runaway agent process cannot take down your entire server. Start withcpus: "1.0" and memory: 512M, then adjust based on actual usage.
Health checks. The health check ensures Docker restarts the container if the web UI stops responding. Without it, a hung process stays running but serves nothing.
Backups. Your agent data is in ./data. Back it up regularly:
# Simple tar backup tar -czf openclaw-backup-$(date +%Y%m%d).tar.gz ./dataOr rsync to another server
rsync -az ./data user@backup-server:/backups/openclaw/
restart: unless-stopped policy means the container restarts on crashes and on server reboot — without you needing to set up systemd units.
Nginx reverse proxy. Do not expose the OpenClaw UI directly on port 3000 in production. Put Nginx in front with SSL:
server {
listen 443 ssl;
server_name agent.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/agent.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/agent.yourdomain.com/privkey.pem;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}With these practices in place, your OpenClaw Docker setup is ready for long-term production use.
Is Docker the Best Way to Install OpenClaw?
For most users — yes. Docker provides isolated environments, one-command updates (docker pull), easy rollbacks, and the ability to run multiple instances. The only cases where a native installation is preferable: if you need maximum performance on limited hardware (Raspberry Pi) or if your hosting provider doesn't support Docker.