OpenClaw + Docker: Containerized Setup
Run OpenClaw in Docker with a production-ready setup: Dockerfile, docker-compose.yml with persistent volumes, environment variables, and health checks.
#Why Docker?
Docker gives you a repeatable, isolated environment for OpenClaw. Benefits:
- Consistent setup across any machine (Mac, Linux, Windows, cloud)
- Easy updates — pull new image, restart container
- Isolation — OpenClaw can't accidentally affect your host system
- Portability — move your setup between machines by copying config files
Docker adds a small overhead (~50-100MB RAM) but OpenClaw runs well inside containers. If you're on a VPS with limited resources (1GB RAM), consider running directly on the host instead.
#Prerequisites
- Docker Engine installed (docs.docker.com/get-docker)
- Docker Compose v2 (included with modern Docker Desktop)
# Verify Docker is installeddocker --version # Docker version 24.x+docker compose version # Docker Compose version v2.x+#Step 1: Project Structure
Create a directory for your OpenClaw Docker setup:
mkdir ~/openclaw-docker && cd ~/openclaw-dockerYou'll create these files:
openclaw-docker/├── docker-compose.yml├── Dockerfile├── .env└── workspace/ ├── SOUL.md ├── USER.md ├── MEMORY.md └── memory/#Step 2: Dockerfile
nano DockerfileFROM node:22-slim# Install system dependenciesRUN apt-get update && apt-get install -y \ curl \ git \ && rm -rf /var/lib/apt/lists/*# Create non-root userRUN useradd -m -s /bin/bash openclaw# Install OpenClaw globallyRUN npm install -g openclaw# Switch to openclaw userUSER openclawWORKDIR /home/openclaw# Create workspace directoryRUN mkdir -p .openclaw/workspace# Health checkHEALTHCHECK --interval=30s --timeout=10s --retries=3 \ CMD openclaw status || exit 1# Start OpenClaw gatewayCMD ["openclaw", "gateway", "start", "--foreground"]#Step 3: docker-compose.yml
nano docker-compose.ymlversion: '3.8'services: openclaw: build: . container_name: openclaw-agent restart: unless-stopped # Mount your workspace and config as persistent volumes volumes: - ./workspace:/home/openclaw/.openclaw/workspace - openclaw-config:/home/openclaw/.openclaw - openclaw-skills:/home/openclaw/openclaw/skills # Pass environment variables env_file: - .env # Resource limits (optional but recommended) deploy: resources: limits: memory: 512M reservations: memory: 256M # Logging configuration logging: driver: json-file options: max-size: "10m" max-file: "3"volumes: openclaw-config: openclaw-skills:#Step 4: Environment Variables
nano .env# OpenClaw ConfigurationNODE_ENV=production# API Keys (add the ones you use)ANTHROPIC_API_KEY=sk-ant-xxxOPENAI_API_KEY=sk-xxx# Messaging (example: Telegram)TELEGRAM_BOT_TOKEN=123456:ABC-xxx# TimezoneTZ=America/New_YorkNever commit .env to version control! Add it to .gitignore if you're using git.
#Step 5: Set Up Your Workspace
# Create the workspace directorymkdir -p workspace/memory# Create your SOUL.mdnano workspace/SOUL.mdAdd your personality (see SOUL.md Mastery guide for templates).
#Step 6: Build and Run
# Build the Docker imagedocker compose build# Start in the backgrounddocker compose up -d# Check it's runningdocker compose ps# View logsdocker compose logs -f openclaw#Verify It Works
# Check OpenClaw status inside the containerdocker compose exec openclaw openclaw status# Send a test message via your messaging channel#Managing Your Container
#View Logs
# Live logsdocker compose logs -f# Last 100 linesdocker compose logs --tail 100# Logs since 1 hour agodocker compose logs --since 1h#Restart
docker compose restart#Stop
docker compose down # Stop and remove containerdocker compose down -v # Also remove volumes (⚠️ deletes data!)#Shell Access
# Get a shell inside the containerdocker compose exec openclaw bash# Run OpenClaw commandsdocker compose exec openclaw openclaw cron listdocker compose exec openclaw openclaw status#Updating OpenClaw
# Rebuild with latest OpenClaw versiondocker compose build --no-cache# Restart with new imagedocker compose up -d# Verify versiondocker compose exec openclaw openclaw --versionFor zero-downtime updates:
# Build new imagedocker compose build --no-cache# Replace running containerdocker compose up -d --force-recreate#Persistent Data
Your data lives in three places:
| Data | Storage | Survives docker compose down? |
|---|---|---|
| Workspace (SOUL.md, MEMORY.md, etc.) | Bind mount ./workspace | ✅ Yes |
| Config (openclaw.json) | Named volume openclaw-config | ✅ Yes (unless -v flag) |
| Skills | Named volume openclaw-skills | ✅ Yes (unless -v flag) |
docker compose down -v deletes named volumes! Your workspace bind mount is safe, but config and skills would be lost. Always back up before using -v.
#Backup
# Backup workspace (already on host filesystem)tar -czf workspace-backup.tar.gz ./workspace/# Backup Docker volumesdocker run --rm \ -v openclaw-docker_openclaw-config:/data \ -v $(pwd):/backup \ alpine tar -czf /backup/config-backup.tar.gz -C /data .#Docker on Different Platforms
#Mac (Docker Desktop)
Works out of the box. File system performance with bind mounts can be slower than native — consider using named volumes for better performance.
#Linux
Native Docker performance. Best option for production.
#Windows (Docker Desktop with WSL2)
Works well. Make sure WSL2 integration is enabled in Docker Desktop settings.
#ARM (Raspberry Pi / Oracle Cloud)
The node:22-slim base image supports ARM64 natively. No changes needed.
#Troubleshooting
#Container Keeps Restarting
# Check logs for errorsdocker compose logs --tail 50# Common causes:# - Missing API key in .env# - Config file permission issues# - Port conflict#Permission Errors
# Fix workspace ownershipsudo chown -R 1000:1000 ./workspace/# The openclaw user in the container has UID 1000#Can't Connect to Messaging Channel
# Verify env vars are loadeddocker compose exec openclaw env | grep TELEGRAM# Check if container can reach the internetdocker compose exec openclaw curl -s https://api.telegram.org#Next Steps
- Your First 24 Hours — Set up SOUL.md and skills
- Security Hardening — Secure your Docker deployment
- Process Management — Advanced monitoring