OpenClaw logo
TryOpenClaw
Try for $1

How to run OpenClaw with Docker: setup, errors, and what they don't tell you

By Linas Valiukas · March 11, 2026

I've set up OpenClaw in Docker more times than I can count. For clients, for testing, on VPS instances that got wiped because someone forgot to pay the bill. The official docs cover the basics but skip over the parts where things actually go wrong. This is the guide I wish existed when I started.

Prerequisites

You need three things installed on your machine:

On a fresh Ubuntu/Debian VPS, install Docker with:

curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# Log out and back in for group changes to take effect

Verify it works: docker run hello-world. If that fails, fix Docker first. Nothing else matters until that command works.

Pulling the image

Grab the latest OpenClaw image:

docker pull openclaw/openclaw:latest

This downloads about 1.2 GB. On a cheap VPS with slow disk I/O, it can take a while. Don't panic if it seems stuck on "Extracting" — that's normal.

One thing the docs don't mention: pin your version in production. Using :latest means every pull could give you a different version. That's fine for testing. For anything real, use a specific tag like openclaw/openclaw:1.8.2.

The docker-compose.yml file

You can run OpenClaw with a single docker run command. Don't. Use a compose file. It's easier to manage, easier to update, and easier to debug when something breaks at 2am.

Here's a working docker-compose.yml:

version: "3.8"

services:
  openclaw:
    image: openclaw/openclaw:latest
    container_name: openclaw
    restart: unless-stopped
    ports:
      - "5678:5678"
    env_file:
      - .env
    volumes:
      - openclaw_data:/home/openclaw/.openclaw
    networks:
      - openclaw-net

  postgres:
    image: postgres:16-alpine
    container_name: openclaw-db
    restart: unless-stopped
    environment:
      POSTGRES_USER: openclaw
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: openclaw
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - openclaw-net

volumes:
  openclaw_data:
  postgres_data:

networks:
  openclaw-net:

Environment variables

Create a .env file in the same directory as your compose file. This is where most setups go sideways.

# Database
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=openclaw-db
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=openclaw
DB_POSTGRESDB_USER=openclaw
DB_PASSWORD=your_strong_password_here

# Encryption key (generate with: openssl rand -hex 32)
ENCRYPTION_KEY=

# Webhook URL (your public server address)
WEBHOOK_URL=https://your-domain.com/

# Optional: set timezone
GENERIC_TIMEZONE=UTC

The ENCRYPTION_KEY is the one people forget most often. Without it, OpenClaw can't store credentials for your integrations. Generate it and save it somewhere safe. If you lose this key, you lose access to every stored credential in your instance.

The DB_POSTGRESDB_HOST value must match the service name in your compose file. Not localhost. Not an IP address. The service name. Docker's internal DNS handles the rest. This trips up so many people.

Starting it up

With your compose file and .env ready:

docker compose up -d

Check that both containers started:

docker compose ps

You should see two containers with status "Up". If one shows "Restarting" or "Exited," that's your first problem to solve. Check logs with docker logs openclaw or docker logs openclaw-db.

If everything's green, open http://your-server-ip:5678 in your browser. You should see the OpenClaw setup screen.

That was the easy part.

The 5 errors you're going to hit

I've helped dozens of people through their first OpenClaw Docker setup. These five errors come up almost every time. Knowing what they are saves hours.

1. Container exits silently (exit code 0 or 1)

You run docker compose up -d, check the status, and the OpenClaw container has already stopped. No error on screen. Just... gone.

Run docker logs openclaw. Almost every time, it's a missing or malformed environment variable. The container starts, tries to read its config, fails, and shuts down. Common culprits:

Fix: read the logs. The answer is always in the logs. If the log is empty, you have a more fundamental Docker issue — check that the image pulled correctly with docker images.

2. Port already in use

The error looks like this:

Error response from daemon: driver failed programming external connectivity:
Bind for 0.0.0.0:5678 failed: port is already allocated

Something else on your server is using port 5678. Could be a previous OpenClaw container that didn't shut down cleanly. Could be another service entirely.

Find what's using the port:

sudo lsof -i :5678
# or
sudo ss -tlnp | grep 5678

If it's an old container, remove it: docker rm -f openclaw. If it's something else, change the port mapping in your compose file to "8080:5678" and access OpenClaw on port 8080 instead.

3. Gateway disconnected / connection refused

You open the browser, go to your server's IP on port 5678, and get nothing. Connection refused. Or if you're behind a reverse proxy, a 502 Bad Gateway.

Possible causes, in order of likelihood:

Test from the server itself first: curl http://localhost:5678. If that works but external access doesn't, it's a firewall issue. If even localhost fails, the problem is the container.

4. Permission denied on volumes

This one is annoying. You'll see something like:

Error: EACCES: permission denied, open '/home/openclaw/.openclaw/config'

OpenClaw runs as a non-root user inside its container (UID 1000 by default). If you're using bind mounts instead of named volumes, the directory on your host needs to be owned by UID 1000. Named volumes (like in the compose file above) avoid this problem entirely, which is why I recommend them.

If you must use a bind mount for easier backups:

mkdir -p ./openclaw-data
sudo chown -R 1000:1000 ./openclaw-data

Then replace the volume line in your compose file with ./openclaw-data:/home/openclaw/.openclaw.

5. Environment variable not found / wrong format

This is subtler than a missing variable. Your .env file has the variable, but it's formatted wrong. Common ways this happens:

The fix for Windows line endings: sed -i 's/\r$//' .env. I run this reflexively on every .env file now.

Useful commands you'll need

Bookmark these. You'll use them more than you think.

# View logs (follow mode)
docker logs -f openclaw

# Restart after config changes
docker compose restart openclaw

# Full rebuild (pull latest + recreate)
docker compose pull && docker compose up -d

# Check resource usage
docker stats openclaw openclaw-db

# Enter the container shell
docker exec -it openclaw /bin/sh

# Back up the database
docker exec openclaw-db pg_dump -U openclaw openclaw > backup.sql

# Check disk usage of volumes
docker system df -v

The maintenance nobody warns you about

Getting OpenClaw running is step one. Keeping it running is the actual job.

Docker logs grow forever unless you configure rotation. I've seen servers fill their entire disk with container logs. Add this to your compose file under the OpenClaw service:

    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

Then there's updates. OpenClaw releases new versions regularly. Some include breaking changes. There's no automatic migration tool. You pull the new image, restart, and hope your workflows still work. Back up before every update. I mean it. I've seen people lose weeks of workflow configuration because they ran docker compose pull without thinking.

Disk space is another slow-motion problem. Docker images accumulate. Old containers stick around. Unused volumes eat gigabytes. Run docker system prune -a periodically, but carefully — it deletes everything not currently in use.

And restarts. If your server reboots, Docker needs to be set to start on boot (sudo systemctl enable docker), and your containers need restart: unless-stopped in the compose file. Miss either one and your AI assistant goes dark after the next kernel update.

None of this is hard individually. But it stacks up. You become a part-time sysadmin whether you wanted to or not.

Or skip all of this

If you read this whole guide and thought "I don't want to do any of that" — fair. That's why we built TryOpenClaw.ai. Same OpenClaw, no Docker, no server, no .env files. Your instance is running in under 60 seconds. We handle the updates, the logs, the restarts, and the 2am disk space alerts.

Self-hosting is a valid choice if you have the skills and the time. But if what you actually want is an AI assistant that works, not a server to babysit, managed hosting is the shorter path.

LV

Linas Valiukas

Software engineer and founder of TryOpenClaw.ai. Been writing code since age 14.

Try it right now

This is just one example — OpenClaw adapts to whatever you need. Describe any workflow in plain language and it figures out the rest. Pay $1 for a full 24-hour trial, pick your messaging app, and start chatting with your own instance in under 60 seconds. Love it? $39/mo. Not for you? Walk away — we delete everything.

Try OpenClaw for $1

24h full access. No commitment. Cancel anytime.