March 5, 2026
Automation DevOps

How to Install OpenClaw with Docker: The Complete Beginner's Guide

So you've heard about OpenClaw—the local AI agent that connects your favorite messaging apps to powerful LLMs without sending everything to the cloud. You're intrigued. You want to try it. But you've looked at the install docs and thought, "Wait, where do I even start?"

I know, Docker can feel like dark magic if you've never used it before. But here's the thing: Docker is actually your friend here. It's the difference between "configure seventeen different dependencies" and "run one command and it just works." Let me walk you through it.

By the end of this guide, you'll have OpenClaw running locally on your machine, connected to at least one messaging platform, and ready to start building your own AI agent. We're going step-by-step, explaining every flag, every file, and every screen you see. And when something goes wrong (and let's be honest, in tech, something usually does), I've got the five most common gotchas and exactly how to fix them.

Table of Contents
  1. Before You Start: What You Actually Need
  2. Installing Docker Desktop
  3. The Quick Start: One Command to Rule Them All
  4. Breaking Down the Docker Run Command: Line by Line
  5. Setting Up Your LLM Provider: Claude, OpenAI, or Local
  6. Using Claude (Recommended for Beginners)
  7. Using OpenAI (ChatGPT)
  8. Using DeepSeek (Budget Option)
  9. Running Ollama Locally (No API Key Needed)
  10. The First-Run Walkthrough: Getting to the Dashboard
  11. Connecting Your First Messaging Platform
  12. Understanding the Workspace Structure
  13. Docker Compose for a More Permanent Setup
  14. The Five Most Common First-Run Errors (and How to Fix Them)
  15. Error 1: "Port 18789 already in use"
  16. Error 2: "Cannot connect to Docker daemon"
  17. Error 3: "API key is invalid" or "401 Unauthorized"
  18. Error 4: "Cannot find ~/.openclaw" or permission denied
  19. Error 5: "Connection refused" or dashboard won't load
  20. Verifying Everything Works: The Complete Checklist
  21. What's Next: Customization and Persistence
  22. Next Steps: Running Multiple Messaging Platforms
  23. Keeping Your Setup Running: Maintenance and Updates
  24. Understanding Memory and Learning Over Time
  25. The Reality Check: What Docker Does and Doesn't Do
  26. Backing Up Your Agent and Workspace
  27. Common Mistakes (and How to Avoid Them)
  28. You're Ready
  29. Key Takeaways: What You've Built
  30. Related Guides

Before You Start: What You Actually Need

Let's be honest about prerequisites. You need:

System Requirements:

  • A computer with at least 4GB RAM (8GB recommended, especially if you're running a local LLM). If you're on something with less than 4GB, OpenClaw will struggle. You'll get timeout errors, slow responses, and general pain. 8GB gives you breathing room and lets you run background tasks without OpenClaw strangling.
  • 20GB free disk space (less if you're just using cloud LLMs like Claude; more if you're running Ollama locally). This includes the Docker image itself (~2GB), your workspace data, conversation logs, and memory files. If you're using a local LLM, add another 5-15GB depending on model size.
  • macOS (Intel or Apple Silicon), Linux (Ubuntu, Debian, Fedora, etc.), or Windows (Windows 10 Pro/Enterprise or Windows 11). Docker Desktop runs on all three. Windows Home edition technically works but is not officially supported and tends to have permission issues—if you're on Home, consider using WSL 2 (Windows Subsystem for Linux 2) instead.
  • A stable internet connection. You need this for the initial Docker image download (it's about 2GB). After that, if you're using cloud LLMs, you need internet to talk to the API. If you're running Ollama locally, internet is optional after setup.

Software You Need Installed:

  • Docker Desktop (includes both Docker and Docker Compose). That's literally it. Seriously. Docker Desktop is the only prerequisite. Nothing else. No Node.js pre-installed, no system packages to juggle.

Optional but Useful:

  • A text editor (VS Code, Sublime, Vim, whatever you use). You'll need this if you want to edit SOUL.md, SKILL.md, or MEMORY.md—and you probably will, eventually.
  • Terminal familiarity (but even if you're brand new to the command line, this guide walks you through every command step by step). Don't worry if you've never used a terminal before.
  • At least one messaging platform account (WhatsApp, Telegram, Discord, Slack, Signal—OpenClaw supports 25+ platforms). You don't need all of them, just one to test with. Telegram is easiest for beginners.
  • An API key for at least one LLM (Claude, OpenAI, DeepSeek, Mistral, etc.). Or you can run Ollama locally for zero API costs, though it requires a beefy machine.

What You Don't Need:

  • Node.js installed separately (Docker handles this—it's baked into the Docker image)
  • Python (nope, Docker's got you)
  • Any special programming knowledge or experience
  • A VPS or cloud server (everything runs on your local machine)
  • A GitHub account (not required, though it's useful if you want to share your setup)
  • Linux knowledge (works the same on Windows or macOS)

Installing Docker Desktop

Visit docker.com and download Docker Desktop for your operating system. Install it the way you'd install any other application. Launch it. You should see the Docker menu icon in your system tray/menu bar.

To verify Docker installed correctly, open your terminal and run:

bash
docker --version

You should see something like Docker version 27.0.0, build abc1234. Great. You're ready.

The Quick Start: One Command to Rule Them All

If you want to get OpenClaw running in the next five minutes, here's the one-liner. Don't worry if you don't understand every part yet—we'll break it down after:

bash
docker run -d \
  --name openclaw \
  --restart unless-stopped \
  -p 18789:18789 \
  -v ~/.openclaw:/root/.openclaw \
  -e OPENCLAW_LLM_PROVIDER=claude \
  -e OPENCLAW_API_KEY=sk-your-key-here \
  openclaw/openclaw:latest

Swap out sk-your-key-here with your actual Claude API key (or whatever LLM you're using). That's it. OpenClaw is now running.

Check if it started:

bash
docker logs openclaw

You should see startup logs. Then open your browser to http://localhost:18789 and you'll see the OpenClaw dashboard.

But wait— I know you probably have questions about what that command actually does. Let me explain it properly.

Breaking Down the Docker Run Command: Line by Line

The command above is doing a lot. Let's unwrap it piece by piece so you understand what's happening—because when something breaks, understanding these flags is how you'll fix it.

bash
docker run -d \
  --name openclaw \

docker run tells Docker to start a new container from an image (think of a container as a lightweight virtual machine that runs just OpenClaw and its dependencies). The -d flag means "run in detached mode"—that is, run in the background and give control of the terminal back to you immediately. Without -d, your terminal would get locked waiting for the container to finish (which it never does, since OpenClaw runs indefinitely).

--name openclaw gives the container a friendly, human-readable name. Internally, Docker assigns every container a random ID like a3f2e9b1c4d6. That's impossible to remember. By naming it "openclaw", you can refer to it later with commands like docker logs openclaw or docker restart openclaw instead of looking up that random ID every time.

bash
  --restart unless-stopped \

This flag is critical for reliability. --restart unless-stopped tells Docker: "If OpenClaw crashes or exits unexpectedly, automatically restart it. Also, if my machine reboots, automatically restart it when the system comes back up." This is the difference between "I ran it once and it's gone now" and "I set it and forget it, it just works."

The unless-stopped part is important. It means "restart automatically, unless I explicitly stopped it with docker stop openclaw." So if you need to troubleshoot something, you can stop the container manually, and it won't try to restart on you. That gives you breathing room to figure out what's wrong. Once you fix it, docker restart openclaw starts it again.

Without this flag, your agent dies the moment anything goes wrong—a memory leak, an unexpected shutdown, a host reboot—and you don't notice until someone complains that the bot isn't responding.

bash
  -p 18789:18789 \

-p is port mapping. Ports are how your machine routes network traffic to specific applications. This says: "Take port 18789 inside the Docker container (where OpenClaw is running) and map it to port 18789 on my actual machine."

The format is -p [your-machine-port]:[container-port]. The first number is what you type into your browser. The second number is what the container is listening on. So if OpenClaw listens on port 18789 inside the container but you want to access it on port 9000 on your machine, you'd use -p 9000:18789. Then you'd visit http://localhost:9000 instead of http://localhost:18789.

Why 18789 specifically? It's somewhat arbitrary. It's high enough (above port 1024) that it doesn't require admin/root privileges. It's unlikely to conflict with common services like web servers (80), HTTPS (443), or SSH (22). The creator just picked something memorable-ish and went with it.

Pro tip: If you're running multiple containers, they each need a different port. You can run OpenClaw on 18789, another instance on 18790, and so on. Or you can change the mapping to something like -p 9000:18789 so port 18789 inside the container maps to 9000 on your machine.

bash
  -v ~/.openclaw:/root/.openclaw \

-v creates a volume mount—this is where the persistence magic happens. Let me explain what's happening here because this is absolutely critical.

  • ~/.openclaw is a directory on your machine (the ~ is shorthand for your home directory: /Users/yourname/ on macOS, /home/yourname/ on Linux, or C:\Users\yourname\ on Windows)
  • /root/.openclaw is where OpenClaw expects to find its data inside the Docker container
  • By mounting them together with -v source:destination, you're saying "make this folder on my machine the same as that folder in the container"

Here's why this matters: Docker containers are ephemeral. When you stop a container, everything inside it—files, data, configuration—is deleted by default. Without this volume mount, when you shut down OpenClaw, your entire workspace would vanish. Your SOUL.md, your custom skills, your conversation logs, your memory—all gone.

With this volume mount, when OpenClaw writes data to /root/.openclaw inside the container, it's actually writing to ~/.openclaw on your hard drive. So when the container shuts down, all that data is still sitting on your machine, safe and sound. The next time you start OpenClaw, it reads the same data from ~/.openclaw and picks up right where it left off.

This is also how you back up your entire agent—just copy ~/.openclaw/ somewhere safe, and you're done.

One gotcha: If your home directory path has spaces in it (like C:\Users\John Smith\), you need to quote it: -v "~/.openclaw:/root/.openclaw". Or use the absolute path without the ~: -v /Users/John Smith/.openclaw:/root/.openclaw.

bash
  -e OPENCLAW_LLM_PROVIDER=claude \
  -e OPENCLAW_API_KEY=sk-your-key-here \

-e sets environment variables—these are basically configuration options passed to the container. Here we're telling OpenClaw two things: (1) what LLM to use (Claude), and (2) the API key to authenticate with that LLM.

When OpenClaw starts up inside the container, it reads these environment variables and configures itself accordingly. You can pass as many -e flags as you need. We'll cover more of these in the LLM provider section below.

Important security note: Your API key is sensitive. Never put it in a command you're going to share with someone else (like on StackOverflow or in documentation). Better approach: store it in an environment file (.env) or use your system's credential store. More on this in the "Common Mistakes" section.

bash
  openclaw/openclaw:latest

Finally, this specifies which Docker image to run. The format is [registry]/[repository]:[tag]. Let's break it down:

  • openclaw/openclaw is the image name. It's hosted on Docker Hub (Docker's official image repository). The first openclaw is the username/organization, the second is the repository name. Think of it as the "template" for the container.
  • :latest is a tag. Tags are versions. :latest means "grab the newest version currently available." If you wanted a specific version, you could use :v2.1.0 or :v1.9.5. This is useful if a new version has breaking changes and you want to stick with the old one.

When you run this command, Docker checks if you already have openclaw/openclaw:latest downloaded. If not, it downloads it (about 2GB). Then it creates a container from that image and starts it up.

Setting Up Your LLM Provider: Claude, OpenAI, or Local

The OPENCLAW_LLM_PROVIDER and OPENCLAW_API_KEY are critical. OpenClaw supports multiple backends. Let's cover the most common:

bash
-e OPENCLAW_LLM_PROVIDER=claude \
-e OPENCLAW_API_KEY=sk-ant-your-actual-key-here

Get your API key from console.anthropic.com. It starts with sk-ant-. Don't share this with anyone.

Using OpenAI (ChatGPT)

bash
-e OPENCLAW_LLM_PROVIDER=openai \
-e OPENCLAW_API_KEY=sk-your-openai-key-here \
-e OPENAI_MODEL=gpt-4

Your OpenAI key starts with sk-. Get it from platform.openai.com/api-keys.

Using DeepSeek (Budget Option)

bash
-e OPENCLAW_LLM_PROVIDER=deepseek \
-e OPENCLAW_API_KEY=sk-your-deepseek-key-here

DeepSeek is much cheaper than Claude or OpenAI. Get your key at platform.deepseek.com.

Running Ollama Locally (No API Key Needed)

If you want to run an LLM entirely on your machine without any API calls:

bash
-e OPENCLAW_LLM_PROVIDER=ollama \
-e OLLAMA_MODEL=llama2 \
-e OLLAMA_BASE_URL=http://host.docker.internal:11434

You'll need to install Ollama separately on your machine first. The http://host.docker.internal:11434 URL is Docker's special way of saying "reach out to my host machine" (on Windows it's the same; on Linux it's http://172.17.0.1:11434 or you use --network host).

Fair warning: Running Ollama locally with a decent model requires a powerful machine. But if you have it, you get complete privacy—nothing leaves your computer.

The First-Run Walkthrough: Getting to the Dashboard

Once your container is running, open your browser and go to http://localhost:18789. You should see the OpenClaw dashboard. It looks something like this:

  • Left sidebar: Navigation (Home, Platforms, Skills, Memory, Settings)
  • Main area: A welcome screen asking you to connect a messaging platform
  • Top right: Settings and profile menu

The dashboard is a web interface for managing your OpenClaw instance. Everything you do here is actually stored in that ~/.openclaw directory we mounted earlier.

Connecting Your First Messaging Platform

Click on Platforms in the sidebar. You'll see a list of 25+ supported platforms: WhatsApp, Telegram, Discord, Slack, Signal, Messenger, iMessage, and more.

Let's say you want to connect Telegram (easy for testing):

  1. Click Telegram
  2. Follow the prompt to create a new Telegram bot via BotFather (Telegram's bot creation tool)
  3. Copy the bot token into the field
  4. Click Connect

Within a minute, you should see a status showing "Connected" or "Active." Send a message to your new bot in Telegram. OpenClaw will respond using your configured LLM.

Congratulate yourself. You just set up a local AI agent. That's not trivial.

Understanding the Workspace Structure

Behind the scenes, OpenClaw has created ~/.openclaw/ on your machine with this structure:

~/.openclaw/
├── config.yaml              # Global configuration
├── platforms/               # Messaging platform configs (Telegram, Discord, etc.)
├── workspace/               # Your workspace (skills, memory, SOUL.md)
│   ├── SKILL.md            # System prompt for custom skills
│   ├── SOUL.md             # Personality and behavior config
│   ├── MEMORY.md           # Long-term memory
│   ├── skills/             # Your custom skill definitions
│   └── logs/               # Daily conversation logs
├── models/                  # Cache for locally-run LLMs
└── cache/                   # Temporary files

You can edit SOUL.md to change how your agent behaves. Edit SKILL.md to teach it new tricks. Every conversation gets logged to logs/. This is a workspace-first system—your ~/.openclaw directory is the source of truth.

Docker Compose for a More Permanent Setup

The docker run command works, but if you want something more serious—or if you're planning to run multiple services (like adding Ollama for local LLM support)—Docker Compose is the way to go.

Create a file called docker-compose.yaml in a folder on your machine:

yaml
version: "3.8"
 
services:
  openclaw:
    image: openclaw/openclaw:latest
    container_name: openclaw
    restart: unless-stopped
    ports:
      - "18789:18789"
    volumes:
      - ~/.openclaw:/root/.openclaw
    environment:
      OPENCLAW_LLM_PROVIDER: claude
      OPENCLAW_API_KEY: sk-ant-your-key-here
    networks:
      - openclaw-net
 
networks:
  openclaw-net:
    driver: bridge

In the same folder, run:

bash
docker compose up -d

Done. It's the same as the docker run command, but it's saved in a file so you can reproduce it, version it, or add more services later.

To see logs:

bash
docker compose logs -f openclaw

To stop it:

bash
docker compose down

To update to a new version:

bash
docker compose pull
docker compose up -d

The Five Most Common First-Run Errors (and How to Fix Them)

You're going to hit one of these. Don't panic. They're all fixable. I've seen all of them, and they all have straightforward solutions.

Error 1: "Port 18789 already in use"

What you see:

Error response from daemon: driver failed programming external connectivity on endpoint openclaw ...
Bind for 0.0.0.0:18789 failed: port is already in use.

Why it happened: Something else on your machine is already using port 18789. This could be another Docker container, a locally installed service, a development server, or anything else that claimed that port first.

How to diagnose it:

The error message is telling you exactly what's wrong: the port is taken. You need to figure out what's using it.

Fix:

bash
# Find what's using port 18789
# macOS/Linux:
lsof -i :18789
 
# Windows PowerShell:
Get-NetTCPConnection -LocalPort 18789
 
# Windows Command Prompt:
netstat -ano | findstr :18789

This will show you which process is using the port. Once you know what it is, you have two options:

Option A: Stop the other service (if it's something you don't need running)

bash
# macOS/Linux: Kill the process by PID
kill -9 [PID]
 
# Windows: Stop the service or kill the process
taskkill /PID [PID] /F

Option B: Use a different port (the easier option)

bash
# Instead of 18789, use 18790, 19000, or any other high-numbered port
docker run -d \
  --name openclaw \
  --restart unless-stopped \
  -p 18790:18789 \
  -v ~/.openclaw:/root/.openclaw \
  -e OPENCLAW_LLM_PROVIDER=claude \
  -e OPENCLAW_API_KEY=sk-your-key-here \
  openclaw/openclaw:latest
 
# Now visit http://localhost:18790 instead

The key thing: the first number in -p 18790:18789 is what you use in your browser. The second number is what the container listens on (must stay 18789). So traffic comes in on 18790, Docker routes it to 18789 inside the container, and OpenClaw responds.

Error 2: "Cannot connect to Docker daemon"

What you see:

error during connect: This error may indicate that the docker daemon is not running.

Or sometimes:

Error: connect ENOENT /var/run/docker.sock

Or on Windows:

Error response from daemon: The system cannot find the file specified.

Why it happened: Docker Desktop isn't running. The Docker daemon is the background service that actually runs containers. Without it, the docker command can't do anything.

How to diagnose it:

You can't run any Docker commands. Try this:

bash
docker ps

If you get the error above, Docker's not running.

Fix:

  1. Find and open Docker Desktop:

    • macOS: Open Applications → Docker
    • Windows: Open Start menu → Docker Desktop
    • Linux: If you installed Docker from a package manager, it might be a service. Run sudo systemctl start docker
  2. Wait for it to fully start. This can take 30-60 seconds. You should see the Docker icon appear in your system tray (Windows/Linux) or menu bar (macOS).

  3. Verify it's running:

    bash
    docker ps

    If this shows a list of containers (or is empty but no error), Docker is running.

  4. Try your OpenClaw command again.

On Linux, Docker might not start automatically. Add it to your startup services:

bash
sudo systemctl enable docker
sudo systemctl start docker

On Windows, if Docker Desktop won't start, you might need to enable virtualization in your BIOS (particularly on older Windows 10 machines). This is outside the scope here, but a quick web search for "enable virtualization Windows" + your CPU model will guide you.

Error 3: "API key is invalid" or "401 Unauthorized"

What you see:

The dashboard loads, everything looks fine, but when you send a message to your bot, you get an error like:

Error: 401 Unauthorized

Or the bot just doesn't respond at all. Or you see in the logs:

Authentication failed: Invalid API key

Why it happened: Your API key is wrong, expired, or your account has no credits/usage remaining. Or you're using the key for the wrong provider (e.g., OpenAI key with Claude settings).

How to diagnose it:

  1. Check the logs:

    bash
    docker logs openclaw

    Look for "auth", "401", "invalid", or "key" in the output.

  2. Test the key manually (optional but thorough). For Claude:

    bash
    curl -X POST https://api.anthropic.com/v1/messages \
      -H "x-api-key: sk-ant-your-key-here" \
      -H "content-type: application/json" \
      -d '{"model":"claude-3-haiku-20240307","max_tokens":100,"messages":[{"role":"user","content":"hi"}]}'

    If you get a 401 response, the key is invalid.

Fix:

  1. Verify you're using the right key:

  2. Make sure the key is active:

    • Log into your provider's dashboard
    • Check that the key hasn't been deactivated
    • For Claude/OpenAI, verify your account has credits and hasn't been suspended
  3. Check for copy-paste errors:

    • Copy the key again directly from the provider's dashboard
    • Don't rely on memory or a saved version—get it fresh
    • Make sure there are no extra spaces or characters before/after the key
  4. Restart the container with the new key:

    bash
    # Stop the old one
    docker stop openclaw
    docker rm openclaw
     
    # Start with the corrected key
    docker run -d \
      --name openclaw \
      --restart unless-stopped \
      -p 18789:18789 \
      -v ~/.openclaw:/root/.openclaw \
      -e OPENCLAW_LLM_PROVIDER=claude \
      -e OPENCLAW_API_KEY=sk-ant-your-actual-correct-key \
      openclaw/openclaw:latest
     
    # Check the logs
    docker logs openclaw
  5. If it still fails: Make sure you're using the right provider name. It's claude, not anthropic. It's openai, not gpt. Capitalization doesn't matter usually, but spelling does.

Error 4: "Cannot find ~/.openclaw" or permission denied

What you see:

docker: Error response from daemon: error while creating mount point '/root/.openclaw':
mkdir: permission denied

Or on Windows:

error while creating mount point C:\Users\...: permission denied

Why it happened: Docker doesn't have permission to create the directory on your machine. This usually happens if your home directory path has special characters (spaces, accents, etc.) or if there's a permissions issue with the parent directory.

How to diagnose it:

Check if the directory exists:

bash
ls -la ~/.openclaw  # macOS/Linux
dir "%USERPROFILE%\.openclaw"  # Windows

If it doesn't exist, Docker will try to create it. If the creation fails, you get this error.

Fix:

Option A: Create the directory manually first

bash
# macOS/Linux:
mkdir -p ~/.openclaw
 
# Windows PowerShell:
New-Item -ItemType Directory -Path "$env:USERPROFILE\.openclaw" -Force

Then run your docker command again.

Option B: If your path has spaces, quote it

bash
# macOS/Linux (usually doesn't have this issue)
docker run -v "~/.openclaw:/root/.openclaw" ...
 
# Windows (common issue):
docker run -v "C:\\Users\\John Smith\\.openclaw:/root/.openclaw" ...

The quotes tell Docker to treat the entire path as a single string, even if it has spaces.

Option C: Use absolute path instead of tilde (safest)

bash
# macOS:
docker run -v /Users/yourname/.openclaw:/root/.openclaw ...
 
# Linux:
docker run -v /home/yourname/.openclaw:/root/.openclaw ...
 
# Windows:
docker run -v C:\\Users\\yourname\\.openclaw:/root/.openclaw ...

Replace yourname with your actual username. You can find your username by running:

bash
# macOS/Linux:
whoami
 
# Windows:
echo %USERNAME%

Option D: Check permissions (if it still fails)

bash
# macOS/Linux: Make sure the parent directory is writable
chmod 755 ~
 
# Windows PowerShell: Run as Administrator if permission issues persist
# (right-click Docker Desktop icon → Run as Administrator)

Error 5: "Connection refused" or dashboard won't load

What you see:

You open your browser and go to http://localhost:18789. The page either says "Connection refused" or just hangs and times out.

Why it happened: The container is either not running at all, or it's running but the OpenClaw service inside didn't start properly.

How to diagnose it:

bash
# First: Check if the container exists and is running
docker ps
 
# Look for a container named "openclaw" with status "Up X minutes"
# If it's not there or status is "Exited", the container crashed
 
# Check the logs to see what went wrong
docker logs openclaw
 
# Look for error messages, stack traces, or anything suspicious

Fix:

Step 1: Is the container running?

bash
docker ps
 
# If you don't see openclaw in the list, check what happened
docker ps -a  # Shows all containers, including stopped ones

If the container status is "Exited", it crashed. Look at the logs:

bash
docker logs openclaw

Step 2: Restart it and watch the logs

bash
docker restart openclaw
 
# In another terminal window, watch the logs in real-time
docker logs -f openclaw
 
# You should see startup messages. Wait 10-15 seconds.
# If you see errors, that's your clue.

Step 3: If startup fails, try a simpler configuration

Sometimes a configuration option is invalid and breaks startup. Try the minimal version:

bash
docker stop openclaw
docker rm openclaw
 
docker run -d \
  --name openclaw \
  -p 18789:18789 \
  -v ~/.openclaw:/root/.openclaw \
  openclaw/openclaw:latest
 
# Wait 10 seconds
sleep 10
 
# Check logs
docker logs openclaw
 
# Try the dashboard
# http://localhost:18789

If this works, the issue was with one of the environment variables. Add them back one at a time until you find the culprit.

Step 4: Check resource constraints

If the container keeps crashing, it might be running out of memory:

bash
docker stats openclaw
 
# Shows CPU and memory usage. If memory is at 90%+ and it's crashing, that's your issue

If so, increase Docker's memory allocation (in Docker Desktop settings) or switch to a smaller LLM model.

Step 5: Nuclear option (if nothing else works)

Delete everything and start fresh:

bash
docker stop openclaw
docker rm openclaw
rm -rf ~/.openclaw  # WARNING: This deletes your config. Back it up first if you care about it.
 
# Start fresh with minimal setup
docker run -d \
  --name openclaw \
  -p 18789:18789 \
  -v ~/.openclaw:/root/.openclaw \
  -e OPENCLAW_LLM_PROVIDER=claude \
  -e OPENCLAW_API_KEY=sk-ant-test-key \
  openclaw/openclaw:latest

This gives you a clean slate. Once it works with minimal config, you can add complexity back.

Verifying Everything Works: The Complete Checklist

Before you move on to customizing your setup, make sure these all pass. This isn't just paranoia—if any of these fails, you know exactly what to debug.

Container & Service Checks:

  • docker ps shows an openclaw container with status Up X minutes (not "Exited")

    bash
    docker ps | grep openclaw
    # Should show: openclaw ... Up 5 minutes
  • The container restarted itself if you stopped it (verify --restart unless-stopped is working)

    bash
    docker restart openclaw
    sleep 5
    docker ps | grep openclaw
    # Should show a recent restart time

Dashboard & Web Access:

  • http://localhost:18789 loads in your browser without connection errors
  • The page shows the OpenClaw logo and interface (not a blank page or error)
  • You can see the navigation menu on the left (Home, Platforms, Skills, Memory, Settings)

Configuration Files:

  • ~/.openclaw/ directory exists on your machine

    bash
    ls -la ~/.openclaw/
    # Should show: openclaw.json, workspace/, skills/, memory/, credentials/, cache/
  • ~/.openclaw/workspace/ contains the core personality files

    bash
    ls -la ~/.openclaw/workspace/
    # Should show: SOUL.md, AGENTS.md, USER.md, COMMANDS.md, skills/, state.json
  • ~/.openclaw/openclaw.json is readable (check it doesn't have syntax errors)

    bash
    cat ~/.openclaw/openclaw.json | head -10
    # Should show valid JSON, not gibberish

Messaging Platform Connection (at least one):

  • You've clicked on "Platforms" in the dashboard sidebar
  • You can see the list of supported platforms (Telegram, Discord, etc.)
  • You've connected at least one platform (Telegram is easiest for testing)
  • The platform shows status "Connected" or "Active" in the dashboard

End-to-End Message Test:

  • Send a test message to your connected platform bot (e.g., send "hello" to your Telegram bot)
  • The agent responds within 10 seconds (might be slower on first query, that's normal)
  • The response is coherent and in the agent's configured voice
  • The response comes from your configured LLM (check the dashboard logs to verify)

Memory & Logging:

  • Conversation logs exist in your workspace logs directory

    bash
    tail ~/.openclaw/workspace/logs/conversation_log.jsonl
    # Should show recent conversation entries with timestamps
  • Daily memory logs exist

    bash
    ls -la ~/.openclaw/memory/daily/
    # Should show files like 2026-03-17.jsonl

Backup System (if enabled):

  • ~/.openclaw/backup/ directory exists
  • At least one backup file is present (.tar.gz files)

All checked? You're officially running OpenClaw. Seriously. You did it. Most people get stuck somewhere in the first 5 errors, but you made it through. Congratulations.

What's Next: Customization and Persistence

Now that OpenClaw is running, you might want to:

Customize your agent's personality: Edit ~/.openclaw/workspace/SOUL.md. This file defines your agent's voice, values, and behavior. Change it and the agent's responses will change.

Teach it new skills: Edit or create files in ~/.openclaw/workspace/skills/. Skills are how you define specialized abilities (summarizing documents, running code, querying databases, etc.). More on this in the SKILL.md documentation.

Check the conversation logs: Look in ~/.openclaw/workspace/logs/. Every conversation is logged here so you can review what your agent has been doing.

Set up multiple platforms: Go back to the dashboard and connect WhatsApp, Discord, Slack, etc. Your agent will respond consistently across all of them.

Upgrade to a self-hosted LLM: If you want to run a local model, install Ollama, then change your environment variables to point to it. You'll get complete privacy with no API costs.

Backup your workspace: Since everything in ~/.openclaw persists on your machine, you can backup that folder like any other important directory. You're never locked in to Docker—it's just a convenient way to run the software.

Next Steps: Running Multiple Messaging Platforms

Once you have OpenClaw working with one platform, connecting additional ones is straightforward. The beauty of the system is that your agent presents a consistent personality across all of them.

Why connect multiple platforms?

Different platforms have different use cases. You might use Telegram for quick testing, Discord for community interactions, Slack for work discussions, and WhatsApp for personal messages. Your agent, configured with the same SOUL.md and SKILL.md, responds consistently everywhere.

The process for each platform:

  1. Go to the Platforms page in the dashboard
  2. Click Add Platform
  3. Select the platform you want (Discord, Slack, Signal, iMessage, etc.)
  4. Follow the platform-specific setup (each one has different requirements)
  5. Click Connect

Each platform has slightly different authentication flows. Discord requires you to create a bot application and give it a token. Slack requires OAuth. WhatsApp uses webhooks. But the dashboard walks you through each one.

One thing to understand: when you connect multiple platforms, they all talk to the same OpenClaw instance. A message on Discord and a message on Telegram both get processed by the same Claude model, with the same memory, the same skill set. That's powerful—it means you get a unified AI agent across your entire communication ecosystem.

Keeping Your Setup Running: Maintenance and Updates

So OpenClaw is running. Now what? Here are the maintenance tasks you'll actually encounter.

Checking that it's still running:

bash
docker ps

If you see your openclaw container with status "Up", you're good. If you don't see it, it crashed or you manually stopped it.

Restarting if something feels off:

bash
docker restart openclaw

This stops the container and immediately restarts it. It's like rebooting your computer, but just for OpenClaw.

Updating to a new version:

OpenClaw gets updates. To upgrade:

bash
docker pull openclaw/openclaw:latest
docker stop openclaw
docker rm openclaw
docker run -d \
  --name openclaw \
  --restart unless-stopped \
  -p 18789:18789 \
  -v ~/.openclaw:/root/.openclaw \
  -e OPENCLAW_LLM_PROVIDER=claude \
  -e OPENCLAW_API_KEY=sk-your-key \
  openclaw/openclaw:latest

Or with Docker Compose:

bash
docker compose pull
docker compose up -d

Your workspace persists through the entire upgrade. Config, skills, memory, logs—all of it stays.

Monitoring logs:

If something goes wrong, logs are your best friend:

bash
# Real-time logs
docker logs -f openclaw
 
# Last 50 lines
docker logs --tail 50 openclaw
 
# Logs since a specific time
docker logs --since 2024-01-15T12:00:00 openclaw

Most issues show up immediately in the logs. API key problems, port conflicts, memory issues—they all get logged.

Understanding Memory and Learning Over Time

OpenClaw has a three-tier memory system. Understanding it helps you get the most out of your agent.

Tier 1: Conversation Context

This is immediate. When you send a message to OpenClaw, it includes the previous N messages in the conversation as context. The agent can refer back to what you said earlier in the same conversation. By default, this goes back about 10 messages (you can configure this).

Tier 2: Daily Logs

Every message is saved to ~/.openclaw/workspace/logs/. These are timestamped, so you can review conversations from yesterday, last week, last month. The agent can't automatically access these during conversations (that would be too much context to send to the LLM), but you can manually reference them.

Tier 3: Long-term Memory

Edit ~/.openclaw/workspace/MEMORY.md to store things you want the agent to always remember. This file is included in every prompt, so if you write "The user's favorite color is blue" in MEMORY.md, the agent will always know that, across all conversations.

This is the hidden power of OpenClaw. Most chatbots forget everything between conversations. OpenClaw doesn't. You control what it remembers.

The Reality Check: What Docker Does and Doesn't Do

Here's the honest truth about what we just set up:

Docker is not making OpenClaw run on the cloud or making it available to other people. It's not magic. What it's doing is:

  1. Packaging OpenClaw's dependencies (Node.js, system libraries, etc.) so you don't have to install them yourself
  2. Running the OpenClaw service on your local machine in a controlled environment
  3. Managing ports and data volumes so everything persists

Everything still runs locally. Your messages stay on your machine (except the ones sent to your LLM provider's API, if you're using Claude, OpenAI, etc.). Your workspace is in ~/.openclaw on your hard drive. You own it.

If you want to run OpenClaw on a VPS (like on AWS or DigitalOcean), you'd use the same Docker command on that remote server, and then you'd need to handle reverse proxies, SSL certificates, and authentication. But that's a different article.

Backing Up Your Agent and Workspace

Since your entire agent configuration lives in ~/.openclaw/, backing it up is trivial. It's just a folder on your computer.

Simple backup:

bash
# Copy your workspace somewhere safe
cp -r ~/.openclaw ~/backups/openclaw-backup-$(date +%Y-%m-%d)
 
# Or use your favorite backup tool (Time Machine, Backblaze, etc.)

Backup to external drive:

bash
# Create a backup archive
tar -czf ~/backup-openclaw.tar.gz ~/.openclaw/
 
# Copy it somewhere (USB drive, cloud storage, etc.)

Restoring from backup:

bash
# Stop the running instance
docker stop openclaw
docker rm openclaw
 
# Restore your backup
rm -rf ~/.openclaw
cp -r ~/backups/openclaw-backup-2024-01-15 ~/.openclaw
 
# Start it again
docker run -d \
  --name openclaw \
  --restart unless-stopped \
  -p 18789:18789 \
  -v ~/.openclaw:/root/.openclaw \
  -e OPENCLAW_LLM_PROVIDER=claude \
  -e OPENCLAW_API_KEY=sk-your-key \
  openclaw/openclaw:latest

The important thing: you can move your agent between machines by just copying the ~/.openclaw/ folder. Your agent isn't locked to your computer—it travels with you.

Common Mistakes (and How to Avoid Them)

Here are the things most people get wrong the first time. Learn from their pain so you don't repeat it.

Mistake 1: Not using --restart unless-stopped

The problem: You start OpenClaw without the restart policy. Three weeks later, your machine reboots (Windows updates, power loss, whatever). OpenClaw doesn't come back automatically. Your bot is offline and you don't notice for hours.

Why it's bad: You promised people your bot would be available. It's not. They're annoyed. You're scrambling to restart it manually.

The fix: Always, always include --restart unless-stopped in your docker run command:

bash
docker run -d \
  --name openclaw \
  --restart unless-stopped \  # THIS LINE. Never forget it.
  -p 18789:18789 \
  -v ~/.openclaw:/root/.openclaw \
  -e OPENCLAW_LLM_PROVIDER=claude \
  -e OPENCLAW_API_KEY=sk-your-key \
  openclaw/openclaw:latest

Or in Docker Compose:

yaml
services:
  openclaw:
    image: openclaw/openclaw:latest
    restart: unless-stopped # THIS LINE.
    # ... rest of config

The unless-stopped part means: "Restart automatically on reboot, unless I manually stopped this container." So if you need to troubleshoot, you can docker stop openclaw and it won't restart on you.

Mistake 2: Accidentally sharing your API key

The problem: You copy your docker run command to share with a colleague or post on StackOverflow. The command includes your API key in plaintext. Now someone (maybe not on purpose) has access to your billing account.

Why it's bad: API keys are credentials. They're like passwords. Whoever has them can make API calls on your account and rack up costs. If they're malicious, they could also exfiltrate data or mess with your systems.

The fix: Never hardcode secrets in commands. Use environment files instead.

bash
# Create a .env file in your openclaw directory
cat > ~/.openclaw/.env << EOF
OPENCLAW_API_KEY=sk-ant-your-actual-key-here
OPENCLAW_LLM_PROVIDER=claude
EOF
 
# Reference it in docker run
docker run -d \
  --name openclaw \
  --restart unless-stopped \
  -p 18789:18789 \
  -v ~/.openclaw:/root/.openclaw \
  --env-file ~/.openclaw/.env \
  openclaw/openclaw:latest

Now your command doesn't include secrets. Only the .env file does, and that's local to your machine (and not in your command history).

Even better: Don't commit .env files to version control. Add it to .gitignore. And if you use Docker Compose, the same applies:

yaml
# docker-compose.yaml
version: "3.8"
services:
  openclaw:
    image: openclaw/openclaw:latest
    container_name: openclaw
    restart: unless-stopped
    ports:
      - "18789:18789"
    volumes:
      - ~/.openclaw:/root/.openclaw
    env_file: .env # Reads from .env file

Then .env is just:

OPENCLAW_API_KEY=sk-ant-your-key
OPENCLAW_LLM_PROVIDER=claude

Mistake 3: Running out of disk space with logs and cache

The problem: OpenClaw logs every single conversation. After three months, your ~/.openclaw/workspace/logs/ directory is 5GB. Your disk is full. Docker can't allocate space for new images. Everything breaks.

Why it's bad: Full disk means slow performance, crashes, and the inability to update OpenClaw or other software.

The fix: Monitor disk usage periodically:

bash
# Check the size of your openclaw directory
du -sh ~/.openclaw/
 
# Check specifically logs
du -sh ~/.openclaw/workspace/logs/
 
# Check cache
du -sh ~/.openclaw/cache/

If logs are getting large, you have two options:

Option A: Archive old logs (safer—keeps history)

bash
# Compress logs older than 90 days
find ~/.openclaw/workspace/logs/ -type f -mtime +90 -exec gzip {} \;
 
# This turns conversation.log into conversation.log.gz, saving ~70% space

Option B: Delete old logs (dangerous—loses history)

bash
# Delete logs older than 6 months
find ~/.openclaw/workspace/logs/ -type f -mtime +180 -delete

For cache (safe to delete—it's just temporary data):

bash
# Clear entire cache (will be regenerated)
rm -rf ~/.openclaw/cache/*
 
# Or just the temp directory
rm -rf ~/.openclaw/cache/temp/*

Pro tip: Set up a monthly cron job to do this automatically:

bash
# macOS/Linux: Edit your crontab
crontab -e
 
# Add this line (runs on the 1st of every month at 2am)
0 2 1 * * find ~/.openclaw/workspace/logs/ -type f -mtime +90 -exec gzip {} \;

Mistake 4: Forgetting to test before going live

The problem: You set up OpenClaw connected to your company Slack. It's been running for two days, nobody tested it, and then someone asks it a question. The response is... weird. Factually wrong. Offensive. A disaster.

Why it's bad: Your agent is now representing you or your company. Bad responses reflect badly on you. The damage is fast and public.

The fix: Always test in a sandboxed environment first. Steps:

  1. Test locally with Telegram (easiest, private, fast)

    • Create a test Telegram bot via BotFather
    • Connect it to OpenClaw
    • Send it a variety of messages: questions, jokes, requests, edge cases
    • Read the responses carefully. Do they match your expectations?
  2. Check the logs

    bash
    docker logs -f openclaw
    # Watch in real-time as you send messages
  3. Review conversation history

    bash
    tail -20 ~/.openclaw/workspace/logs/conversation_log.jsonl
    # See the last 20 interactions
  4. Test with your team (if applicable)

    • Have 2-3 people send test messages
    • Capture responses
    • Discuss: is the tone right? Are the facts correct? Does it behave well?
  5. Only then connect it to important channels (work Slack, customer Discord, etc.)

Mistake 5: Ignoring resource limits

The problem: You start OpenClaw with default settings on a machine that's already running a bunch of other stuff. Docker competes for CPU and memory. OpenClaw gets starved. Responses are slow. The LLM times out. Messages get dropped.

Why it's bad: Your agent seems broken when really it's just resource-constrained.

The fix: Monitor resource usage:

bash
# Watch live CPU and memory
docker stats openclaw
 
# You should see something like:
# CONTAINER   CPU %  MEM USAGE / LIMIT
# openclaw    5.2%   512MB / 4GB

If memory is consistently >80% of its limit, you have a problem. Fix it by:

  1. Increase Docker's memory allocation (Docker Desktop settings)
  2. Use a smaller LLM model (switch from Opus to Haiku if using Claude)
  3. Disable memory-heavy features (like long-term memory if you don't need it)

Mistake 6: Not backing up your config

The problem: You've spent weeks customizing SOUL.md, SKILL.md, and your skills. Then your hard drive dies. Or you accidentally rm -rf ~/.openclaw. Everything is gone.

Why it's bad: Months of configuration work, lost.

The fix: Back up ~/.openclaw/ regularly:

bash
# Simple backup (daily)
cp -r ~/.openclaw ~/Backups/openclaw-$(date +%Y-%m-%d).bak
 
# Or use tar for compression
tar -czf ~/Backups/openclaw-$(date +%Y-%m-%d).tar.gz ~/.openclaw/
 
# Or sync to cloud storage (assuming you use Dropbox, iCloud, etc.)
cp -r ~/.openclaw ~/Dropbox/Backups/

Or set up automated backups with a cron job:

bash
# Edit crontab
crontab -e
 
# Add daily backup at 2am
0 2 * * * tar -czf ~/Backups/openclaw-$(date +\%Y-\%m-\%d).tar.gz ~/.openclaw/

You're Ready

For now, you've got a working local AI agent. One that connects to your messaging apps. That remembers things. That can be customized to your needs.

That's genuinely powerful.


Key Takeaways: What You've Built

Let's recap what you've accomplished here. You didn't just run a Docker command—you've set up a local AI system that stays under your control. No data shipped to the cloud. No third-party services required (except your chosen LLM provider). No lock-in. Just an agent running on your machine that's ready to connect to Slack, Discord, Matrix, or any platform you've configured.

Here's what actually matters:

First, Docker gave you repeatability. You're not juggling Python versions, Node dependencies, or environment variables. One command, and OpenClaw is running. Tomorrow, next month, or on a different machine—same command, same result. That's the value of containerization.

Second, your workspace lives in ~/.openclaw/—the source of truth. Everything your agent learns, every skill you teach it, every personality tweak you make: it's all in that folder on your hard drive. You own it. You can back it up. You can move it. You can version control it if you want to get serious about it. Docker is just the delivery mechanism; your agent is the permanent part.

Third, you're now positioned to customize. SOUL.md controls personality. SKILL.md and the skills directory control abilities. Conversation logs in ~/.openclaw/workspace/logs/ let you audit and understand what your agent is doing. This isn't a black box—it's a system you can inspect, modify, and improve.

The gotchas we covered—permission issues, disk space, API key fumbles, port conflicts—these will happen to you eventually. When they do, you know what to check. You know how to read logs. You know that the container can be destroyed and restarted without losing anything because your actual workspace persists on disk. That's the maturity point where Docker stops feeling like magic and starts feeling like a tool you actually understand.

From here, the next steps are: pick a messaging platform, configure your API keys, write your first custom skill, or share your agent setup with your team. You've got the foundation. The rest is creativity and iteration.


Want to go deeper? Check out these related articles to expand your OpenClaw skills:


Need help implementing this?

We build automation systems like this for clients every day.

Discuss Your Project