guide2026-03-26

How to Install OpenClaw with Docker (Complete Guide 2026)

How to Install OpenClaw with Docker (Complete Guide 2026)

Docker is the recommended and most reliable way to run OpenClaw. It handles dependencies, isolation, and makes upgrades straightforward. This guide covers everything from a basic docker run to a production-ready docker-compose setup with health checks and persistent storage.


Why Docker for OpenClaw?

OpenClaw depends on a specific Node.js version and compiles a WebAssembly sandbox at startup. Docker ensures:

  • Consistent environment across Linux, macOS, and Windows
  • Easy upgrades by pulling a new image tag
  • Resource limits (critical: OpenClaw needs 2048 MB RAM)
  • Isolation from other services on the same host

Prerequisites

  • Docker Engine 24+ installed (official install docs)
  • Docker Compose v2 (included with modern Docker Desktop and Docker Engine)
  • At least 2 GB free RAM allocated to Docker
  • A Telegram bot token from @BotFather
  • An Anthropic API key (or other supported LLM provider key)

Verify your Docker installation:

docker --version        # Docker version 24.x.x or higher
docker compose version  # Docker Compose version v2.x.x or higher

Quick Start: docker run

The fastest way to get OpenClaw running:

docker run -d   --name openclaw   --restart unless-stopped   -p 8080:8080   -e ANTHROPIC_API_KEY=sk-ant-your-key   -e NODE_OPTIONS=--max-old-space-size=1536   -m 2048m   alpine/openclaw:latest   node /app/openclaw.mjs gateway

Critical: Always set -m 2048m. OpenClaw's WASM sandbox compilation peaks at ~1.3 GB RAM. Without this limit Docker may not reserve enough memory, and without enough available RAM the container will be OOM-killed (exit code 137).

Watch startup logs:

docker logs -f openclaw

The gateway takes about 5 minutes on first start (WASM compilation). Be patient.


Production Setup: docker-compose

For production, use docker-compose.yml for reproducible, declarative configuration.

Project structure

openclaw/
├── docker-compose.yml
├── .env
└── config/
    └── openclaw.json

docker-compose.yml

version: "3.9"

services:
  openclaw:
    image: alpine/openclaw:latest
    container_name: openclaw
    restart: unless-stopped
    command: node /app/openclaw.mjs gateway
    ports:
      - "8080:8080"
    volumes:
      - ./config:/home/node/.openclaw
      - openclaw_data:/home/node/.openclaw/data
    environment:
      - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
      - NODE_OPTIONS=--max-old-space-size=1536
      - OPENCLAW_GATEWAY_TOKEN=${OPENCLAW_GATEWAY_TOKEN}
    deploy:
      resources:
        limits:
          memory: 2048M
        reservations:
          memory: 512M
    healthcheck:
      test: ["CMD", "node", "-e", "require('http').get('http://127.0.0.1:18789/health', r => process.exit(r.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 360s
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

volumes:
  openclaw_data:

.env file

ANTHROPIC_API_KEY=sk-ant-your-key-here
OPENCLAW_GATEWAY_TOKEN=your-secret-token-here

Security tip: Never commit your .env file to git. Add it to .gitignore.


OpenClaw Configuration File

Create config/openclaw.json:

{
  "gateway": {
    "mode": "local",
    "controlUi": {
      "dangerouslyDisableDeviceAuth": true
    }
  },
  "agents": {
    "default": {
      "model": "claude-3-5-sonnet-20241022"
    }
  },
  "channels": {
    "telegram": {
      "enabled": true,
      "botToken": "123456789:AABBcc-your-bot-token",
      "dmPolicy": "open"
    },
    "whatsapp": {
      "enabled": false,
      "dmPolicy": "open",
      "selfChatMode": true,
      "accounts": {
        "default": {
          "dmPolicy": "open"
        }
      }
    }
  }
}

Important configuration rules:

  • gateway.mode MUST be "local" — other values cause exit=1
  • Do NOT include agents.defaults.systemPrompt or temperature — these are unrecognized keys that cause exit=1
  • Do NOT include channels.http — the HTTP channel does not exist in current builds
  • For WhatsApp, do NOT use selfPhoneMode, dms, or groups — use selfChatMode, dmPolicy instead

Environment Variables Reference

| Variable | Required | Description | |---|---|---| | ANTHROPIC_API_KEY | Yes* | Anthropic API key for Claude models | | NODE_OPTIONS | Yes | Set to --max-old-space-size=1536 | | OPENCLAW_GATEWAY_TOKEN | Recommended | Pre-set auth token for Control UI | | OPENAI_API_KEY | No | For GPT models (alternative to Anthropic) |

*One LLM API key is required.


Persistent Storage with Volumes

OpenClaw stores session data, channel auth, and cache in /home/node/.openclaw. Mount this as a volume to persist across container restarts and upgrades:

volumes:
  - ./config:/home/node/.openclaw        # Config files (bind mount)
  - openclaw_data:/home/node/.openclaw/data  # Runtime data (named volume)

Using a named volume for the data subdirectory ensures Docker manages the data lifecycle. Use bind mounts for config files so you can edit them directly on the host.


Health Checks

The start_period: 360s (6 minutes) in the health check config gives OpenClaw time to compile the WASM sandbox before health checks begin. Without this, Docker may restart the container prematurely thinking it's unhealthy.

Check container health status:

docker inspect openclaw --format='{{.State.Health.Status}}'

Multi-Container Setup with Redis

For high-traffic deployments, you can add Redis for session caching:

services:
  openclaw:
    # ... (same as above)
    environment:
      - REDIS_URL=redis://redis:6379
    depends_on:
      redis:
        condition: service_healthy

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 3

volumes:
  openclaw_data:
  redis_data:

Resource Limits by Use Case

| Use Case | Memory Limit | CPU | |---|---|---| | Development / testing | 2048 MB | No limit | | Single-user production | 2048 MB | 1.0 CPU | | Multi-user production | 4096 MB | 2.0 CPUs | | High-traffic | 4096+ MB | 4.0 CPUs |


Updating OpenClaw

To upgrade to the latest version:

docker compose pull
docker compose up -d

Or with plain Docker:

docker pull alpine/openclaw:latest
docker stop openclaw && docker rm openclaw
# Re-run your docker run command

Platform Differences

Linux: Full Docker Engine support. Run exactly as shown. Best performance.

macOS (Docker Desktop): Works but Docker Desktop limits memory by default. Go to Settings → Resources → Memory and set to at least 4 GB.

Windows (Docker Desktop + WSL2): Works with WSL2 backend. Ensure WSL2 memory isn't capped in %USERPROFILE%\.wslconfig. Add:

[wsl2]
memory=4GB

Production Deployment Checklist

Before going live, verify:

  • [ ] -m 2048m or memory: 2048M is set
  • [ ] NODE_OPTIONS=--max-old-space-size=1536 is set
  • [ ] Config JSON validated (python3 -m json.tool openclaw.json)
  • [ ] No unrecognized config keys (causes silent exit=1)
  • [ ] gateway.mode: "local" is set
  • [ ] Bot token is in the config JSON (not just env var)
  • [ ] start_period in healthcheck is at least 360 seconds
  • [ ] Named volume created for persistent data
  • [ ] .env file excluded from git
  • [ ] Logs configured with rotation (max-size: "10m")
  • [ ] Firewall only exposes necessary ports

Troubleshooting

Exit code 1 immediately after start: Config syntax error or unrecognized key. Check logs and validate JSON.

Exit code 137 (OOM): Not enough RAM. Increase -m limit or free up memory on host.

Port already in use: Change the host port (left side of -p): -p 9090:8080.

"Cannot connect to Docker daemon": Run sudo systemctl start docker or add your user to the docker group.


Prefer Zero-Maintenance?

Running OpenClaw in Docker works great but requires server maintenance, updates, and monitoring. ClawMates handles all of this automatically — deploy in one click for $29.99/month with no server management required.

Ready to try it?

Try ClawMates free for 7 days. Set up your AI assistant in 5 minutes.

Start Free Trial