Skip to main content
← Back to guides
12 min readNashville Lobster Ranch

OpenClaw Docker Setup: Container Config Explained

openclawdockerdeployment

TL;DR: OpenClaw runs as a stack of 5-7 Docker containers working together: the agent runtime, web gateway, memory store (ChromaDB or Qdrant), message broker, tool servers, and optionally a monitoring dashboard. The docker-compose.yml file orchestrates all of them, handling startup order, networking, volume persistence, and health checks. Common Docker problems include port conflicts, insufficient memory causing OOMKill restarts, volume permission errors on Linux, and containers starting before their dependencies are ready. Production deployments should add resource limits to prevent any single container from consuming all available memory, persistent volumes for data that survives container restarts, and a restart policy so services recover from crashes automatically. The default Docker configuration also exposes the gateway on all interfaces (0.0.0.0), a security risk that CrowdStrike flagged across 135,000 exposed instances. This guide covers the full container architecture and how to configure it properly.

How does OpenClaw's Docker architecture work?

OpenClaw runs as a multi-container application where each service (agent runtime, gateway, memory store, message broker, tools, scheduler) operates in its own isolated container, communicating over an internal Docker network. This microservices approach allows independent updates and scaling but also means more components can break.

If you haven't installed OpenClaw yet, start with our complete installation guide. This guide goes deeper on the Docker-specific configuration.

Here's what's actually running when you type docker compose up:

The container stack

| Container | Purpose | Typical Memory | Port | |-----------|---------|---------------|------| | openclaw-core | Agent runtime — the brain that decides what to do | 512MB-1GB | Internal only | | openclaw-gateway | Web interface and API endpoint | 256MB | 3000 (default) | | chromadb | Vector memory store for agent context | 256MB-512MB | 8000 (internal) | | redis | Message broker and caching layer | 128MB | 6379 (internal) | | openclaw-tools | Tool execution server (email, calendar, etc.) | 256MB-512MB | Internal only | | openclaw-scheduler | Cron-like task scheduling | 128MB | Internal only | | openclaw-monitor | Optional health dashboard | 128MB | 8080 (optional) |

That's 1.5-3 GB of memory just for the base stack, before your agent starts doing any actual work. This is why the minimum system requirement is 4 GB of RAM, and 8 GB is recommended.

What does docker-compose.yml control?

The docker-compose.yml file defines how all containers work together, including startup order, environment configuration, data persistence, restart behavior, and resource limits. Understanding these sections is essential for debugging and production tuning.

The docker-compose.yml file in the OpenClaw repository defines how all these containers work together. Here's what the key sections mean in plain English.

Services

Each service block defines a container. The critical settings for each:

services:
  openclaw-core:
    image: openclaw/core:latest
    depends_on:
      chromadb:
        condition: service_healthy
      redis:
        condition: service_started
    env_file: .env
    volumes:
      - ./data/core:/app/data
    restart: unless-stopped
    deploy:
      resources:
        limits:
          memory: 1G

The depends_on directive controls startup order. The core service waits for ChromaDB to be healthy before starting, not just running, but actually ready to accept connections. This prevents the most common startup error: the agent trying to access memory before the database is ready.

The env_file directive loads your configuration from the .env file. Every container that needs LLM API keys, OAuth credentials, or configuration settings references this file.

The volumes directive maps directories inside the container to your host filesystem. Without volumes, all data disappears when a container restarts. The ./data/core directory persists agent state, conversation history, and configuration across restarts.

The restart: unless-stopped policy tells Docker to automatically restart the container if it crashes. "Unless-stopped" means it restarts on failure but stays stopped if you explicitly stop it with docker compose stop.

The deploy.resources.limits section caps how much memory a container can use. Without this, a memory leak in one container can consume all available RAM and crash everything else. Set these limits explicitly.

Networks

networks:
  openclaw-net:
    driver: bridge

All containers communicate over an internal Docker network. This means ChromaDB and Redis are not exposed to the internet; only the gateway container has an external port mapping. This is good security architecture by default, but only if you also restrict the gateway's binding address.

Volumes

volumes:
  chroma-data:
  redis-data:
  core-data:

Named volumes persist data across container restarts and recreations. If you run docker compose down and then docker compose up again, your agent's memory and configuration survive because they're stored in these volumes, not inside the ephemeral containers.

How should you configure Docker for production?

Production configuration requires four changes from the defaults: resource limits on every container to prevent memory exhaustion, restart policies for automatic recovery, health checks on all services for proper dependency ordering, and the gateway bound to localhost instead of all interfaces.

The default docker-compose.yml is designed for development and testing. For production (meaning an agent that runs 24/7 handling real workflows) you need to adjust several things.

Add resource limits to every container

Without memory limits, a single misbehaving container can consume all available RAM and crash the entire stack:

services:
  openclaw-core:
    deploy:
      resources:
        limits:
          memory: 1G
          cpus: '1.0'
  chromadb:
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: '0.5'

Set restart policies

Containers crash. Dependencies fail. Servers reboot. Your restart policy determines whether your agent comes back automatically or waits for you to notice:

# For critical services
restart: unless-stopped

# For optional services (monitoring)
restart: on-failure

Configure health checks

Health checks let Docker know whether a container is actually working, not just running. The default OpenClaw compose file includes health checks for some services but not all:

chromadb:
  healthcheck:
    test: ["CMD", "curl", "-f", "http://localhost:8000/api/v1/heartbeat"]
    interval: 30s
    timeout: 10s
    retries: 3
    start_period: 40s

Add health checks to every service. This makes depends_on with condition: service_healthy actually work, preventing cascade failures during startup.

Bind the gateway to localhost

This cannot be overstated. The default configuration binds the gateway to 0.0.0.0, meaning it accepts connections from anywhere:

# DANGEROUS DEFAULT
openclaw-gateway:
  ports:
    - "0.0.0.0:3000:3000"

# SECURE ALTERNATIVE
openclaw-gateway:
  ports:
    - "127.0.0.1:3000:3000"

Binding to 127.0.0.1 means only processes on the same machine can reach the gateway. If you need external access, put a reverse proxy (Nginx or Caddy) in front of it with authentication. This is exactly what CrowdStrike and Microsoft recommend.

What Docker errors will you actually encounter?

The most common Docker errors come from port conflicts, insufficient memory, networking issues, volume permissions, and dependency timing. Each has a specific fix, and most can be diagnosed from the container logs.

These are the errors you'll actually encounter, drawn from the OpenClaw Discord and GitHub issues.

"Cannot start service: port is already allocated"

Another process is using the same port. Find it and stop it:

# Find what's using port 3000
sudo lsof -i :3000

# Or change the port in docker-compose.yml
ports:
  - "127.0.0.1:3001:3000"

Containers stuck in "Restarting" loop

Usually a memory issue. Check:

docker compose logs openclaw-core --tail 50

If you see OOMKilled in the output, you need more RAM or stricter memory limits on other containers. Our VPS hosting comparison covers which plans provide enough headroom. If you see configuration errors, your .env file has missing or malformed values.

"Error response from daemon: driver failed programming external connectivity"

Docker's networking layer hit a conflict. The nuclear option that usually works:

docker compose down
docker network prune
docker compose up -d

Volume permission errors on Linux

Docker containers run as root by default, but the host filesystem may have different ownership. If you see "permission denied" errors when containers try to write data:

# Fix ownership on data directories
sudo chown -R 1000:1000 ./data/

The specific UID (1000) may vary depending on the container's configuration. Check the Dockerfile for the service to confirm which user it runs as.

ChromaDB failing health checks

ChromaDB can be slow to initialize, especially on first run when it needs to create its database. Increase the start_period in the health check:

chromadb:
  healthcheck:
    start_period: 120s  # Give it 2 minutes on first run

"Conflict. The container name is already in use"

A leftover container from a previous run. Remove it:

docker compose down --remove-orphans
docker compose up -d

Which Docker Compose commands will you actually use?

| Command | What it does | |---------|--------------| | docker compose up -d | Start all services in the background | | docker compose down | Stop and remove all containers (volumes persist) | | docker compose logs -f | Follow live logs from all services | | docker compose logs [service] --tail 100 | Last 100 lines from one service | | docker compose restart [service] | Restart a single service | | docker compose pull | Pull latest images (for updates) | | docker compose ps | Show status of all containers | | docker compose exec [service] sh | Open a shell inside a running container | | docker compose down -v | Stop and remove everything including data volumes (destructive) |

Warning on docker compose down -v: The -v flag deletes all named volumes. This destroys your agent's memory, conversation history, and configuration. Use it only when you want a completely fresh start.

How do you update OpenClaw Docker containers?

Pull the latest images and recreate containers with docker compose pull followed by docker compose up -d. Docker Compose only recreates containers whose images changed, and your data persists in volumes. Always read the changelog before updating in production.

OpenClaw releases updates frequently. The update process:

# Pull latest images
docker compose pull

# Recreate containers with new images
docker compose up -d

Docker Compose is smart enough to only recreate containers whose images have changed. Your data persists in volumes.

Before updating in production, read the changelog. Breaking changes, like the January 2026 OAuth migration, can require configuration updates before the new version works. Test updates on a separate machine or in a staging environment when possible.

When does Docker become more trouble than it's worth?

Docker adds a layer of complexity between you and the software. For developers who work with containers daily, it's invisible. For everyone else, it's an ongoing source of frustration that requires specialized knowledge to debug and maintain.

Every Docker error message requires Docker knowledge to debug. Every configuration change requires understanding how Docker maps ports, volumes, and networks. Every update requires pulling images and recreating containers. If something goes wrong at 3 AM, you need to be comfortable SSH-ing into a server and reading container logs.

The real cost of self-hosting OpenClaw isn't just the initial setup; it's maintaining Docker knowledge and availability for the life of your agent. Understanding the full cost picture helps frame whether that investment makes sense compared to a managed deployment.

Key takeaways

  • OpenClaw runs as 5-7 interconnected Docker containers consuming 1.5-3 GB of memory before the agent starts working.
  • The docker-compose.yml file controls startup order, networking, data persistence, restart behavior, and resource limits for every container.
  • Always bind the gateway to 127.0.0.1 instead of the default 0.0.0.0 to prevent public exposure.
  • Set memory limits on every container to prevent a single service from crashing the entire stack.
  • Health checks with depends_on conditions prevent cascade failures during startup.
  • Most Docker errors (port conflicts, OOMKill, permission issues) are diagnosable from container logs and have straightforward fixes.
  • Production deployments need resource limits, restart policies, health checks, and localhost-only gateway binding at minimum.

Frequently Asked Questions

Can I use Docker Desktop instead of Docker Engine?

Docker Desktop works fine for development and testing on Mac and Windows. For production Linux servers, Docker Engine is lighter and doesn't require a GUI. Docker Desktop also has licensing restrictions for commercial use in larger organizations; Docker Engine doesn't.

How do I back up my OpenClaw Docker data?

Back up the named volumes and your .env file. The simplest approach is backing up the ./data/ directory (if using bind mounts) or using docker volume commands to export named volumes. Schedule automated backups; your agent's memory and configuration are irreplaceable if lost.

Can I run OpenClaw in Kubernetes instead of Docker Compose?

Yes, but it's overkill for a single agent. Kubernetes makes sense if you're deploying agents for multiple users or need auto-scaling. For one agent serving a small team, Docker Compose provides everything you need with far less complexity.

How much disk space does OpenClaw use over time?

The Docker images total 2-4 GB. Agent data (memory, logs, conversation history) grows at roughly 100-500 MB per month depending on activity level. Adding community skills increases both storage usage and the number of running containers. Plan for 50 GB of storage to be comfortable for the first year, and monitor usage quarterly.

What happens if a container crashes while the agent is mid-task?

If a container crashes, the restart: unless-stopped policy brings it back automatically. The agent loses the in-progress task but retains its memory and configuration from persistent volumes. Incomplete actions (like a half-sent email) depend on the specific tool; most service integrations are designed to be idempotent, so retrying after a crash doesn't create duplicates.


Docker is powerful infrastructure, and infrastructure needs someone watching it. If you'd rather focus on what your agent does instead of how it runs, we handle the entire stack. Containers, security, monitoring, updates — all managed.

Ready to get your agent started?

White-glove OpenClaw deployment for Nashville executives and teams. We handle the tech so you can focus on what matters.

Get Started — $5,000 All-In

Related Guides