# OpenClaw + Docker: Containerized Setup

Canonical: https://clawdocx.com/docs/getting-started-docker
Author: Sam Okafor
Difficulty: INTERMEDIATE
Published: 2026-02-24
Updated: 2026-02-25

> 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

> **Note**
>
> 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](https://docs.docker.com/get-docker/))
- Docker Compose v2 (included with modern Docker Desktop)

```bash
# Verify Docker is installed
docker --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:

```bash
mkdir ~/openclaw-docker && cd ~/openclaw-docker
```

You'll create these files:

```
openclaw-docker/
├── docker-compose.yml
├── Dockerfile
├── .env
└── workspace/
    ├── SOUL.md
    ├── USER.md
    ├── MEMORY.md
    └── memory/
```

---

## Step 2: Dockerfile

```bash
nano Dockerfile
```

```dockerfile
FROM node:22-slim

# Install system dependencies
RUN apt-get update && apt-get install -y \
    curl \
    git \
    && rm -rf /var/lib/apt/lists/*

# Create non-root user
RUN useradd -m -s /bin/bash openclaw

# Install OpenClaw globally
RUN npm install -g openclaw

# Switch to openclaw user
USER openclaw
WORKDIR /home/openclaw

# Create workspace directory
RUN mkdir -p .openclaw/workspace

# Health check
HEALTHCHECK --interval=30s --timeout=10s --retries=3 \
    CMD openclaw status || exit 1

# Start OpenClaw gateway
CMD ["openclaw", "gateway", "start", "--foreground"]
```

---

## Step 3: docker-compose.yml

```bash
nano docker-compose.yml
```

```yaml
version: '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

```bash
nano .env
```

```bash
# OpenClaw Configuration
NODE_ENV=production

# API Keys (add the ones you use)
ANTHROPIC_API_KEY=sk-ant-xxx
OPENAI_API_KEY=sk-xxx

# Messaging (example: Telegram)
TELEGRAM_BOT_TOKEN=123456:ABC-xxx

# Timezone
TZ=America/New_York
```

> **Warning**
>
> Never commit `.env` to version control! Add it to `.gitignore` if you're using git.

---

## Step 5: Set Up Your Workspace

```bash
# Create the workspace directory
mkdir -p workspace/memory

# Create your SOUL.md
nano workspace/SOUL.md
```

Add your personality (see [SOUL.md Mastery guide](/docs/soul-md-guide) for templates).

---

## Step 6: Build and Run

```bash
# Build the Docker image
docker compose build

# Start in the background
docker compose up -d

# Check it's running
docker compose ps

# View logs
docker compose logs -f openclaw
```

### Verify It Works

```bash
# Check OpenClaw status inside the container
docker compose exec openclaw openclaw status

# Send a test message via your messaging channel
```

---

## Managing Your Container

### View Logs

```bash
# Live logs
docker compose logs -f

# Last 100 lines
docker compose logs --tail 100

# Logs since 1 hour ago
docker compose logs --since 1h
```

### Restart

```bash
docker compose restart
```

### Stop

```bash
docker compose down       # Stop and remove container
docker compose down -v    # Also remove volumes (⚠️ deletes data!)
```

### Shell Access

```bash
# Get a shell inside the container
docker compose exec openclaw bash

# Run OpenClaw commands
docker compose exec openclaw openclaw cron list
docker compose exec openclaw openclaw status
```

---

## Updating OpenClaw

```bash
# Rebuild with latest OpenClaw version
docker compose build --no-cache

# Restart with new image
docker compose up -d

# Verify version
docker compose exec openclaw openclaw --version
```

For zero-downtime updates:

```bash
# Build new image
docker compose build --no-cache

# Replace running container
docker 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) |

> **Warning**
>
> `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

```bash
# Backup workspace (already on host filesystem)
tar -czf workspace-backup.tar.gz ./workspace/

# Backup Docker volumes
docker 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
```bash
# Check logs for errors
docker compose logs --tail 50

# Common causes:
# - Missing API key in .env
# - Config file permission issues
# - Port conflict
```

### Permission Errors
```bash
# Fix workspace ownership
sudo chown -R 1000:1000 ./workspace/

# The openclaw user in the container has UID 1000
```

### Can't Connect to Messaging Channel
```bash
# Verify env vars are loaded
docker compose exec openclaw env | grep TELEGRAM

# Check if container can reach the internet
docker compose exec openclaw curl -s https://api.telegram.org
```

---

## Next Steps

- [Your First 24 Hours](/docs/first-24-hours) — Set up SOUL.md and skills
- [Security Hardening](/docs/security-hardening) — Secure your Docker deployment
- [Process Management](/docs/process-management) — Advanced monitoring