Docker Installation
Cài đặt OpenClaw với Docker để isolate và dễ manage hơn.
Tại sao dùng Docker?
Advantages:
- ✅ Clean isolation từ host system
- ✅ Easy updates (pull new image)
- ✅ Reproducible setup
- ✅ Resource limits
- ✅ Easy backup (volumes)
vs Native install:
- Native: Faster, less overhead
- Docker: Safer, easier management
Prerequisites
1. Install Docker
Ubuntu/Debian:
# Uninstall old versions
sudo apt-get remove docker docker-engine docker.io containerd runc
# Install dependencies
sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release
# Add Docker GPG key
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# Add repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
# Verify
sudo docker run hello-world
macOS:
# Install Docker Desktop
brew install --cask docker
# Or download from: https://www.docker.com/products/docker-desktop
Windows (WSL2):
- Install Docker Desktop for Windows
- Enable WSL2 backend in settings
- Verify trong WSL terminal:
docker --version
2. Add User to Docker Group (Linux)
sudo usermod -aG docker $USER
# Logout and login lại để apply
Quick Start (Docker Compose)
1. Create Directory
mkdir ~/openclaw-docker
cd ~/openclaw-docker
2. Create docker-compose.yml
version: '3.8'
services:
openclaw:
image: openclaw/openclaw:latest
container_name: openclaw
restart: unless-stopped
# Ports
ports:
- "18789:18789" # Gateway WebSocket
- "18793:18793" # Canvas host
# Volumes
volumes:
- ./config:/root/.openclaw:rw
- ./data:/data:rw
- ./logs:/logs:rw
# Environment
environment:
- NODE_ENV=production
- TZ=Asia/Ho_Chi_Minh
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
- BRAVE_API_KEY=${BRAVE_API_KEY}
# Resources
deploy:
resources:
limits:
cpus: '2.0'
memory: 2G
reservations:
memory: 512M
# Security
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
# Health check
healthcheck:
test: ["CMD", "openclaw", "health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
3. Create .env File
# .env
ANTHROPIC_API_KEY=your_anthropic_key_here
BRAVE_API_KEY=your_brave_key_here
4. Start Container
docker compose up -d
Check logs:
docker compose logs -f openclaw
Expected:
✅ OpenClaw Gateway starting...
✅ Node.js: v22.x.x
✅ Config loaded: /root/.openclaw/openclaw.json
✅ Gateway listening on ws://0.0.0.0:18789
Manual Docker Run
Without docker-compose:
docker run -d \
--name openclaw \
--restart unless-stopped \
-p 18789:18789 \
-p 18793:18793 \
-v $(pwd)/config:/root/.openclaw \
-v $(pwd)/data:/data \
-e ANTHROPIC_API_KEY=your_key \
-e TZ=Asia/Ho_Chi_Minh \
openclaw/openclaw:latest
Configuration
Initial Setup
First run - run wizard:
docker compose exec openclaw openclaw onboard --install-daemon
Follow prompts:
- Choose gateway mode (local/remote)
- Configure Anthropic API
- Setup channels (WhatsApp, Telegram...)
- Install daemon
Edit Config
Mount config volume:
volumes:
- ./config:/root/.openclaw:rw
Edit on host:
vim config/openclaw.json
Restart container:
docker compose restart openclaw
Persistence
Volumes Explained
volumes:
# Config files
- ./config:/root/.openclaw:rw
# Contains: openclaw.json, auth tokens
# User data
- ./data:/data:rw
# Contains: workspaces, files, databases
# Logs
- ./logs:/logs:rw
# Contains: application logs
Backup
# Stop container
docker compose stop openclaw
# Backup volumes
tar -czf openclaw-backup-$(date +%Y%m%d).tar.gz config/ data/ logs/
# Restart
docker compose start openclaw
Restore
# Stop container
docker compose stop openclaw
# Extract backup
tar -xzf openclaw-backup-20260130.tar.gz
# Restart
docker compose start openclaw
Networking
Expose to LAN
Default: localhost only
For LAN access:
services:
openclaw:
ports:
- "0.0.0.0:18789:18789" # All interfaces
cảnh báo
Chỉ expose LAN nếu:
- Trusted network
- Firewall configured
- Gateway auth enabled
Reverse Proxy (Nginx)
nginx.conf:
server {
listen 80;
server_name openclaw.local;
location / {
proxy_pass http://localhost:18789;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
SSL (Let's Encrypt):
certbot --nginx -d openclaw.yourdomain.com
Updates
Update Image
# Pull latest
docker compose pull openclaw
# Recreate container
docker compose up -d --force-recreate
# Verify
docker compose logs -f openclaw
Version Pinning
Specify version:
services:
openclaw:
image: openclaw/openclaw:1.2.3 # Specific version
Available tags:
latest- Latest stable1.2.3- Specific versiondev- Development (unstable)
Multi-Container Setup
With Redis (for scaling)
version: '3.8'
services:
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
- redis-data:/data
command: redis-server --appendonly yes
openclaw:
image: openclaw/openclaw:latest
depends_on:
- redis
environment:
- REDIS_URL=redis://redis:6379
# ... rest of config
volumes:
redis-data:
With Database (PostgreSQL)
services:
postgres:
image: postgres:15-alpine
restart: unless-stopped
environment:
POSTGRES_DB: openclaw
POSTGRES_USER: openclaw
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres-data:/var/lib/postgresql/data
openclaw:
depends_on:
- postgres
environment:
- DATABASE_URL=postgresql://openclaw:${DB_PASSWORD}@postgres:5432/openclaw
volumes:
postgres-data:
Resource Management
CPU Limits
deploy:
resources:
limits:
cpus: '2.0' # Max 2 cores
reservations:
cpus: '0.5' # Reserved
Memory Limits
deploy:
resources:
limits:
memory: 2G # Hard limit
reservations:
memory: 512M # Guaranteed
Disk Limits
# Create volume with size limit (requires ZFS/Btrfs)
docker volume create --driver local \
--opt type=tmpfs \
--opt device=tmpfs \
--opt o=size=5g \
openclaw-data
Monitoring
Container Stats
# Live stats
docker stats openclaw
# Output:
# CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O
# openclaw 15% 512MB / 2GB 25% 1.2MB / 850KB
Logs
# Tail logs
docker compose logs -f openclaw
# Last 100 lines
docker compose logs --tail=100 openclaw
# Since timestamp
docker compose logs --since "2026-01-30T10:00:00" openclaw
Health Checks
# Check health
docker inspect --format='{{.State.Health.Status}}' openclaw
# Health history
docker inspect --format='{{json .State.Health}}' openclaw | jq
Security
Run as Non-Root
# In Dockerfile
RUN useradd -m -s /bin/bash openclaw
USER openclaw
# In docker-compose.yml
services:
openclaw:
user: "1000:1000" # UID:GID
Read-Only Root FS
services:
openclaw:
read_only: true
tmpfs:
- /tmp
- /var/run
Security Options
security_opt:
- no-new-privileges:true
- seccomp=unconfined # Only if needed
cap_drop:
- ALL
cap_add:
- NET_BIND_SERVICE
- CHOWN
Troubleshooting
Container Won't Start
# Check logs
docker compose logs openclaw
# Common issues:
# - Port already in use
# - Invalid config
# - Missing API keys
Fix port conflict:
ports:
- "18790:18789" # Use different host port
Out of Memory
# Check memory usage
docker stats openclaw
# Increase limit
deploy:
resources:
limits:
memory: 4G # Increase from 2G
Permission Denied
# Fix volume permissions
sudo chown -R 1000:1000 config/ data/ logs/
# Or run as root (not recommended)
services:
openclaw:
user: "0:0" # Root
Network Issues
# Check container network
docker network inspect openclaw_default
# Recreate network
docker compose down
docker compose up -d
Production Checklist
- Docker installed & configured
- docker-compose.yml created
- .env with API keys (not committed to git!)
- Volumes configured for persistence
- Resource limits set
- Health checks enabled
- Logs rotation configured
- Backup strategy in place
- Firewall rules configured
- SSL/TLS if exposed to internet
- Monitoring setup (Prometheus/Grafana)
- Auto-restart enabled
Resources
Need help? Discord #docker