What Is Docker? What Is Sandboxing?
New to Docker? No problem. Here's what you need to know in plain English.
When you install software normally, it puts files all over your computer — in your system folders, your home directory, your startup scripts. If something goes wrong, it can be messy to clean up. And if the software has a bug or does something unexpected, it can affect other programs on your machine.
Docker solves this by creating a container — a self-contained, isolated box where your software runs. The software inside the container can't see or touch anything on your computer that you haven't explicitly shared with it.
A shipping container is a sealed, standardized box. You can put anything inside it — furniture, electronics, food — and it loads onto any ship the same way, travels safely, and gets unloaded cleanly. The contents don't mix with other cargo, and if something leaks inside the container, it stays inside the container. Docker containers work exactly like this for software.
Sandboxing is the practice of running software in an isolated environment — a "sandbox" where it can only play with what you give it. For an AI agent like OpenClaw that can browse the web, read files, and run automations, sandboxing adds an important safety layer: even if something goes wrong, the damage is contained.
Why Run OpenClaw in Docker?
Docker isn't just for developers. Here are real benefits for any OpenClaw user.
Safer automation
OpenClaw can execute code and access files. Running it in Docker means it can only access the folders you explicitly share — nothing else on your system is reachable.
Clean install, clean uninstall
No scattered files across your system. To completely remove OpenClaw and all its data, you delete one container and one image. Done.
Easy updates
Update OpenClaw by pulling the new image and restarting the container. No dependency conflicts, no leftover files from the old version.
Works on any machine
Your Docker setup runs identically on Mac, Windows, and Linux. Share your docker-compose.yml with others and they get the exact same environment.
Server deployment ready
When you're ready to run OpenClaw 24/7 on a server or VPS, Docker is the standard way to deploy. The same container you test locally deploys directly.
Safe experimentation
Try experimental configs, new skills, or untrusted code in a container. If anything breaks, destroy the container and start fresh in seconds.
Step 1 — Install Docker
Choose your operating system below for installation instructions.
-
Download Docker Desktop for Mac
Go to docker.com/products/docker-desktop and click Download for Mac. Make sure to pick the right chip — Apple Silicon (M1/M2/M3) or Intel. Not sure which? Click the Apple menu → About This Mac.
-
Install and launch
Open the downloaded
.dmgfile, drag Docker to your Applications folder, and open it. Docker will ask for your admin password — this is needed to install the system components. -
Wait for Docker to start
You'll see a whale icon in your menu bar. When it stops animating (becomes a solid whale), Docker is ready. This usually takes about 30 seconds on first launch.
-
Verify the install
Open Terminal and run:
$ docker --version Docker version 26.1.0, build a96...If you see a version number, you're ready.
-
Enable WSL 2 (Windows Subsystem for Linux)
Docker Desktop on Windows uses WSL 2 as its backend. Open PowerShell as Administrator and run:
wsl --installRestart your computer when prompted. If you already have WSL, run
wsl --updateinstead. -
Download Docker Desktop for Windows
Go to docker.com/products/docker-desktop, download the Windows installer, and run it. Accept the defaults and click Install.
-
Launch Docker Desktop
Open Docker Desktop from the Start menu. Accept the terms of service. Wait for the engine to start (the whale icon in the system tray will stop animating).
-
Verify the install
Open PowerShell or Command Prompt and run:
> docker --version
Docker Desktop works on both Windows Home and Pro. Windows Home uses WSL 2 as the backend (which you installed in step 1). Windows Pro can also use Hyper-V, but WSL 2 is recommended for better performance.
-
Install Docker Engine using the official script
The quickest way on Ubuntu / Debian:
$ curl -fsSL https://get.docker.com | sudo shThis installs Docker Engine, CLI, and Compose in one go.
-
Run Docker without sudo (recommended)
Add your user to the
dockergroup so you don't needsudoevery time:$ sudo usermod -aG docker $USER $ newgrp docker -
Start Docker and enable on boot
$ sudo systemctl enable --now docker -
Verify
$ docker run hello-world Hello from Docker! ✓
There's also a Docker Desktop GUI app for Linux with a visual dashboard. Download it from docs.docker.com/desktop/install/linux-install. It's optional — Docker Engine (CLI only) works great for OpenClaw.
Step 2 — Set Up Your Project Folder
Before writing any Docker files, create a clean folder structure for your OpenClaw project.
my-openclaw/
├── openclaw.json # your OpenClaw config
├── Dockerfile # tells Docker how to build the image
├── docker-compose.yml # easier way to manage the container
├── .env # your API keys (never commit this!)
├── .gitignore # make sure .env and agent.db aren't committed
└── data/ # persistent storage (memory db, logs)
Your .env file will contain API keys. Add it to .gitignore immediately:
- Create a file named
.gitignorein your project folder - Add these two lines:
.envanddata/ - Never commit or share your
.envfile
Step 3 — Write the Dockerfile
A Dockerfile is a recipe that tells Docker how to build a container image for OpenClaw. Each line is a simple instruction — here's a beginner-friendly version with every line explained.
# Start from the official Node.js 20 image (slim = smaller file size)
FROM node:20-slim
# Set the working directory inside the container
WORKDIR /app
# Install OpenClaw globally
RUN npm install -g openclaw
# Copy your config file into the container
COPY openclaw.json .
# Create a directory for persistent data (memory, logs)
RUN mkdir -p /app/data
# Expose the gateway port so your browser/apps can connect
EXPOSE 8080
# The command that runs when the container starts
CMD ["openclaw", "start"]
FROM— picks the base image. We use the official Node.js image so we don't have to install Node ourselves.WORKDIR— sets the folder we work in inside the container, likecd /app.RUN— executes a shell command during the build step.COPY— copies a file from your computer into the container image.EXPOSE— documents which port the app listens on (doesn't actually open the port — that's done in docker-compose).CMD— the default command to run when the container starts.
Step 4 — Docker Compose (Recommended)
Instead of typing long docker run commands every time, Docker Compose lets you define everything in one simple file and start your whole setup with one command.
version: '3.9'
services:
openclaw:
# Build the image from the Dockerfile in this folder
build: .
# Give the container a friendly name
container_name: openclaw-agent
# Restart automatically if it crashes or the server reboots
restart: unless-stopped
# Map host port 8080 to container port 8080
# Format: "host_port:container_port"
ports:
- "8080:8080"
# Load environment variables (API keys) from .env file
env_file:
- .env
# Mount the data folder so memory persists between restarts
# Format: "host_path:container_path"
volumes:
- ./data:/app/data
# Health check: ping the gateway every 30 seconds
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
Step 5 — Environment Variables (.env)
Store all your API keys and secrets in a .env file. Docker Compose reads this file automatically — your keys never get baked into the image.
# AI provider API keys
ANTHROPIC_API_KEY=sk-ant-your-key-here
OPENAI_API_KEY=sk-your-openai-key
# Messaging integrations
TELEGRAM_BOT_TOKEN=1234567890:your-bot-token
DISCORD_BOT_TOKEN=your-discord-token
# Search tool
BRAVE_API_KEY=your-brave-key
Then reference them in your openclaw.json using the $VARIABLE_NAME syntax — OpenClaw substitutes them automatically at runtime:
{
"llm": {
"provider": "anthropic",
"model": "claude-sonnet-4-6",
"apiKey": "$ANTHROPIC_API_KEY" // reads from .env
},
"memory": {
"type": "sqlite",
"path": "/app/data/agent.db" // inside the mounted volume
},
"gateway": {
"host": "0.0.0.0", // must be 0.0.0.0 inside Docker
"port": 8080
}
}
When running in Docker, OpenClaw's gateway must bind to "host": "0.0.0.0" — not 127.0.0.1. The default 127.0.0.1 only allows connections from within the container itself, so your apps outside the container won't be able to reach it. 0.0.0.0 means "accept connections from anywhere that Docker routes to me."
Step 6 — Build and Run
With your files in place, starting OpenClaw in Docker is a single command.
-
Navigate to your project folder
$ cd my-openclaw -
Build the Docker image and start the container
$ docker compose up --build # You'll see the build output, then OpenClaw starting up. # Press Ctrl+C to stop.The first run takes a minute to download the base image and install OpenClaw. Subsequent starts are instant.
-
Run in the background (detached mode)
Add
-dto run the container in the background so it doesn't occupy your terminal:$ docker compose up -d ✓ Container openclaw-agent Started -
Verify it's running
$ docker compose ps NAME STATUS PORTS openclaw-agent running (healthy) 0.0.0.0:8080->8080/tcpYour OpenClaw gateway is now reachable at
http://localhost:8080.
How Volumes & Networking Work
Understanding the relationship between your computer and the container makes troubleshooting much easier.
Your machine ↔ Docker container
./data/ folder
./data → /app/data
/app/data/agent.db
localhost:8080
8080 → 8080
0.0.0.0:8080
Volumes are shared folders between your machine and the container. Without a volume, everything stored inside the container disappears when you delete it — including your agent's memory. The ./data:/app/data volume mount means the container's /app/data folder is actually your local ./data folder. Data survives container restarts and deletions.
Port mapping ("8080:8080") forwards traffic from port 8080 on your machine to port 8080 inside the container. The format is always host_port:container_port. If something else uses port 8080 on your machine, change the left side: "9090:8080" would put OpenClaw at localhost:9090.
Essential Docker Commands
A quick reference for everything you'll need day to day.
| Command | What it does |
|---|---|
| docker compose up -d | Start all services in the background (detached) |
| docker compose down | Stop and remove containers (data in volumes is preserved) |
| docker compose restart | Restart all running containers |
| docker compose logs -f | Stream live logs from all containers (Ctrl+C to stop) |
| docker compose logs openclaw | Show logs from the openclaw service only |
| docker compose ps | Show running containers and their status |
| docker compose up --build -d | Rebuild the image (use after changing the Dockerfile) then start |
| docker compose pull | Pull the latest base image versions |
| docker compose exec openclaw sh | Open a shell inside the running container (for debugging) |
| docker compose down -v | Stop containers AND delete volumes — ⚠️ this deletes your data |
| docker image prune | Delete unused images to free up disk space |
Updating OpenClaw in Docker
Keeping OpenClaw up to date is clean and simple with Docker.
-
Stop the running container
$ docker compose down -
Rebuild the image with the latest OpenClaw version
$ docker compose build --no-cacheThe
--no-cacheflag forces a fresh install rather than using a cached layer — this ensures you get the latest version of OpenClaw from npm. -
Start back up
$ docker compose up -dYour data is preserved because it lives in the
./datavolume on your machine, not inside the container.
Using a Local LLM with Docker
Running Ollama alongside OpenClaw? Here's how to wire them together.
When both OpenClaw and Ollama run in Docker, they're on the same internal network. Use the service name ollama as the hostname instead of localhost:
version: '3.9'
services:
ollama:
image: ollama/ollama
container_name: ollama
restart: unless-stopped
volumes:
- ollama_data:/root/.ollama # persists downloaded models
# Uncomment below for NVIDIA GPU support:
# deploy:
# resources:
# reservations:
# devices:
# - driver: nvidia
# count: all
# capabilities: [gpu]
openclaw:
build: .
container_name: openclaw-agent
restart: unless-stopped
ports:
- "8080:8080"
env_file: .env
volumes:
- ./data:/app/data
depends_on:
- ollama # wait for Ollama to start first
volumes:
ollama_data:
Then in your openclaw.json, point to Ollama using the service name:
"llm": {
"provider": "ollama",
"model": "llama3.1:8b",
"baseUrl": "http://ollama:11434" // "ollama" = the service name above
}
After starting with docker compose up -d, pull a model into the running Ollama container:
$ docker compose exec ollama ollama pull llama3.1:8b
Common Docker Problems & Fixes
Docker Desktop isn't running. Open the Docker Desktop app and wait for it to fully start before running any commands.
Something else on your machine is using port 8080. Change the host port in docker-compose.yml to something unused: "9090:8080". Your gateway will then be at localhost:9090.
Your COPY openclaw.json . line in the Dockerfile only runs at build time. If you change your config after building, you need to rebuild: docker compose up --build -d. Or mount the config as a volume for live updates: add - ./openclaw.json:/app/openclaw.json to the volumes section.
Make sure your .env file is in the same directory as docker-compose.yml, and that it doesn't have any quote marks around the values. Correct: ANTHROPIC_API_KEY=sk-ant-abc123. Wrong: ANTHROPIC_API_KEY="sk-ant-abc123".
Check that the data/ directory exists on your machine and the volume mount is correctly set in docker-compose.yml. Also confirm your openclaw.json memory path points to /app/data/agent.db (the container path, not your local path).
Check the full Troubleshooting guide or view the container logs for detailed error messages: docker compose logs -f openclaw