Why Docker for OpenClaw?
- Isolation: Container boundaries limit blast radius if the agent is compromised
- Reproducibility: Same environment across dev/staging/prod
- Dependency management: All Node.js, system packages, and skills packaged together
- Easy upgrades: Pull new image, restart container
- Resource limits: Prevent runaway agents from exhausting host resources
⚠️ But Beware: Docker ≠ Perfect Security
Container escape vulnerabilities exist (though rare). Docker isolation is a defense-in-depth layer, not a security perimeter. Combine with other controls.
Quick Start: Basic Docker Compose
Start with a minimal docker-compose.yml:
version: '3.8'
services:
openclaw:
image: openclaw/openclaw:latest
container_name: openclaw-agent
restart: unless-stopped
ports:
- "18789:18789" # Gateway API
environment:
- OPENCLAW_MODEL=claude-3-opus-20240229
- OPENCLAW_API_KEY=${ANTHROPIC_API_KEY}
- NODE_ENV=production
volumes:
- ./data:/root/.openclaw # Persistent storage
- ./logs:/var/log/openclaw
networks:
- openclaw-net
networks:
openclaw-net:
driver: bridge
Launch with docker-compose up -d. This runs OpenClaw with your API key from environment, persisting memory and credentials in ./data.
Production Hardening Checklist
1. Use a Non-Root User
The default OpenClaw image runs as root. For production, create and use an unprivileged user:
FROM openclaw/openclaw:latest USER node # or create custom user with adduser # ... rest of config
Or in compose: user: "1000:1000" (map to non-root UID).
2. Restrict Capabilities
Drop Linux capabilities the container doesn’t need. OpenClaw needs some for system access, but not everything:
cap_drop: - NET_RAW - SYS_MODULE - SYS_PTRACE - SETUID - SETGID
Keep only what’s required for your specific tools (usually none if you’re not running shell commands from within the container itself).
3. Read-Only Filesystem Where Possible
Make the container’s root filesystem read-only, mounting only specific writable volumes:
read_only: true volumes: - ./data:/root/.openclaw:rw - ./logs:/var/log/openclaw:rw
This prevents malware from modifying the container image at runtime.
4. Network Segmentation
Place the OpenClaw container on an isolated Docker network. Only allow outbound connections to required services (Anthropic API, your tools).
networks:
openclaw-net:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/24
enable_ipv6: false
Use firewall rules on the host to restrict container egress.
5. Resource Limits
Prevent runaway agents from consuming all host resources:
deploy:
resources:
limits:
cpus: '2.0'
memory: 2G
reservations:
cpus: '0.5'
memory: 512M
Adjust based on expected workload. LLM inference is memory-intensive.
6. Secrets Management
Never hard-code API keys in docker-compose.yml. Use Docker secrets, environment files with strict permissions, or a secrets manager (HashiCorp Vault, AWS Secrets Manager):
# Use secrets
secrets:
anthropic_key:
file: ./secrets/anthropic.key
services:
openclaw:
secrets:
- anthropic_key
environment:
- OPENCLAW_API_KEY_FILE=/run/secrets/anthropic_key
Persistent Storage: Where to Put Your Data
Bind mount these host directories into the container:
~/.openclaw/or/root/.openclaw/→./data:/root/.openclaw(credentials, memory, configuration)/var/log/openclaw/→./logs:/var/log/openclaw(logs for audit)/opt/openclaw-skills/→./skills:/opt/openclaw-skills(if using custom skills)
Ensure these directories are backed up regularly. Loss of .openclaw/credentials/ means re-authenticating all integrations.
Monitoring and Health Checks
Add a health check to your compose file:
healthcheck: test: ["CMD", "curl", "-f", "http://localhost:18789/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s
Then configure Docker to restart on failure. Combine with external monitoring (Prometheus, Datadog) to alert if the container goes down or health check fails.
Updating: Zero-Downtime Deployments
Update the image without stopping your agent:
# Pull latest image docker-compose pull # Recreate container with new image (preserves volumes) docker-compose up -d --no-deps --build openclaw
For mission-critical deployments, consider a blue-green setup: run two instances on different ports, switch a reverse proxy load balancer, then stop the old one.
Security Hardening Complete Example
Here’s a production-ready docker-compose.yml incorporating all recommendations:
version: '3.8'
services:
openclaw:
image: openclaw/openclaw:2026.2.26
container_name: openclaw-prod
restart: unless-stopped
ports:
- "18789:18789"
environment:
- OPENCLAW_MODEL=claude-3-opus-20240229
- OPENCLAW_API_KEY_FILE=/run/secrets/anthropic_key
- NODE_ENV=production
- LOG_LEVEL=info
secrets:
- anthropic_key
volumes:
- ./data:/root/.openclaw:rw
- ./logs:/var/log/openclaw:rw
read_only: true
cap_drop:
- NET_RAW
- SYS_MODULE
- SYS_PTRACE
- SETUID
- SETGID
networks:
- openclaw-net
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:18789/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
deploy:
resources:
limits:
cpus: '2.0'
memory: 2G
reservations:
cpus: '0.5'
memory: 512M
secrets:
anthropic_key:
file: ./secrets/anthropic.key
networks:
openclaw-net:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/24
enable_ipv6: false
Place your Anthropic API key in ./secrets/anthropic.key with chmod 600.
Advanced: Kubernetes Deployment
For organizations already running Kubernetes, OpenClaw can be deployed as a StatefulSet with PersistentVolumeClaims. Basic manifest:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: openclaw
spec:
serviceName: openclaw
replicas: 1
selector:
matchLabels:
app: openclaw
template:
metadata:
labels:
app: openclaw
spec:
containers:
- name: openclaw
image: openclaw/openclaw:2026.2.26
ports:
- containerPort: 18789
env:
- name: OPENCLAW_MODEL
value: "claude-3-opus-20240229"
- name: OPENCLAW_API_KEY
valueFrom:
secretKeyRef:
name: openclaw-secrets
key: anthropic-key
volumeMounts:
- name: data
mountPath: /root/.openclaw
resources:
limits:
memory: "2Gi"
cpu: "2000m"
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 10Gi
Kubernetes offers better orchestration, auto-restart, and integration with cloud secrets managers.
Troubleshooting Common Issues
- Permission denied on data volume: Ensure the mounted directory is owned by UID 1000 (or adjust
userin compose). - Cannot connect to gateway: Check that port 18789 is published and not blocked by firewall.
- API key not working: Verify the key file is mounted correctly and path set in
OPENCLAW_API_KEY_FILE. - High memory usage: Claude Opus needs ~2GB. Use smaller models (
claude-3-haiku) if constrained. - Container exits immediately: Check logs with
docker logs openclaw-prod. Common cause: missing API key.
Isolation vs. Functionality Trade-Offs
Heavy hardening (read-only FS, minimal capabilities) may block features OpenClaw expects:
- Shell commands: Will fail if container lacks necessary capabilities or shell binaries
- Skill installation: May need write access to
/opt/openclaw-skills - Browser automation: Requires additional system dependencies (Chrome/Playwright)
Test your specific use cases in a staging environment before locking down production. Sometimes the safer choice is to not run that capability rather than weaken isolation.
Need Enterprise-Grade OpenClaw Deployment?
Flowix AI provides fully managed OpenClaw infrastructure with security hardening, monitoring, and 24/7 support. Let us handle the complexity while you enjoy the automation.