Tutorials

Deploy OpenClaw in Docker

The secure way to run OpenClaw in production with container hardening and network isolation.

Prerequisites

$ brew install --cask docker

Launch Docker Desktop after installation.

docker_installed

Checks Docker is installed and the daemon is running

Quick Start: Docker Run

1

Run OpenClaw in a container

$ docker run -it --rm -v $(pwd)/workspace:/workspace anthropic/openclaw

This mounts your local workspace directory into the container.

Ephemeral by default
The --rm flag removes the container on exit. Your work is preserved in the mounted volume.
NemoClaw and NanoClaw use Docker too
Both NemoClaw and NanoClaw deploy in Docker mode via Cloud Deploy. NanoClaw takes container isolation further with ephemeral containers and mount allowlists.

Production Setup: Docker Compose

2

Create docker-compose.yml

docker-compose.yml
version: "3.8"

services:
  openclaw:
    image: anthropic/openclaw:latest
    container_name: openclaw
    restart: unless-stopped

    # Security: drop all capabilities, add only what's needed
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE

    # Security: read-only root filesystem
    read_only: true
    tmpfs:
      - /tmp:noexec,nosuid,size=100m

    # Security: no privilege escalation
    security_opt:
      - no-new-privileges:true

    # Resource limits
    deploy:
      resources:
        limits:
          cpus: "2.0"
          memory: 2G
        reservations:
          memory: 512M

    # Volumes
    volumes:
      - ./workspace:/workspace
      - openclaw-config:/home/openclaw/.config

    # Network: use internal network
    networks:
      - openclaw-net

    # Environment
    environment:
      - NODE_ENV=production

networks:
  openclaw-net:
    internal: true  # No external internet access

volumes:
  openclaw-config:
3

Start the stack

$ docker compose up -d
$ docker compose logs -f openclaw

Watch logs to verify startup.

Container Hardening

Clawkeeper's container_security check audits these settings.

Default (insecure)
docker run -it \
  --privileged \
  -v /:/host \
  anthropic/openclaw
Hardened
docker run -it --rm \
  --cap-drop ALL \
  --cap-add NET_BIND_SERVICE \
  --read-only \
  --security-opt no-new-privileges \
  --memory 2g \
  --cpus 2 \
  -v ./workspace:/workspace:rw \
  anthropic/openclaw
container_security

Audits container capabilities, read-only fs, privilege escalation, and resource limits

What each flag does:

  • --cap-drop ALL — removes all Linux capabilities (process, network, filesystem)
  • --cap-add NET_BIND_SERVICE — allows binding to low-numbered ports if needed
  • --read-only — makes the root filesystem immutable (prevents malware persistence)
  • --security-opt no-new-privileges — prevents setuid/setgid escalation
  • --memory 2g — caps memory to prevent DoS via resource exhaustion

Network Isolation

4

Use an internal Docker network

The internal: true setting in Docker Compose prevents the container from reaching the internet directly. If OpenClaw needs external API access, use a reverse proxy or allowlist specific endpoints.

network_isolation

Verifies network isolation between OpenClaw and the LAN

5

Verify network isolation

$ docker compose exec openclaw node -e "require('https').get('https://example.com',r=>{console.log('OPEN');process.exit(0)}).on('error',()=>{console.log('BLOCKED');process.exit(0)})"

You should see BLOCKED if the internal network is configured correctly.

Verify with Clawkeeper

clawkeeper scan

$ npx clawkeeper scan

PASS docker_installed — Docker 24.0.7 runningPASS container_security — All hardening flags appliedPASS network_isolation — Container on internal network

Automate these checks with Clawkeeper

One command scans your entire OpenClaw deployment and gives you an A-F security grade.