Run OpenClaw with Docker Compose on Ubuntu 24.04 LTS

I still think the normal OpenClaw installer is the easiest first run for most people. Docker Compose starts to make sense when your Ubuntu 24.04 LTS VPS already runs other apps in containers and you want OpenClaw to fit into the same routine for config, logs, and updates.

Here I'll use the official Docker setup, keep the important state on the host, and make sure the Control UI works before you start adding channels, plugins, or anything more ambitious. If you want the native install path instead, use How to Install OpenClaw on Ubuntu and Complete Your First Setup first.

OpenClaw's Docker docs call out 2 GB RAM as the practical floor for image builds because 1 GB hosts can run out of memory. The project does not publish a full hardware matrix for every Docker scenario, so treat these as sensible planning numbers rather than hard limits.

  • Minimum test box: 2 vCPU, 2 GB RAM, 20 GB storage

  • Recommended starter VPS: 2 vCPU, 4 GB RAM, 30 to 40 GB storage

  • More comfortable long-running setup: 4 vCPU, 8 GB RAM, 50+ GB storage if you expect more logs, plugins, or local-model experiments

If you already know you'll add extra tooling later, skip the tiny VPS. Paying a little more up front is usually better than fighting memory pressure and disk limits a few days later.

When Docker Compose is the better fit

I would use this route when you want:

  • a containerized Gateway instead of a host-level install

  • easier separation between app runtime and host OS packages

  • a persistent config and workspace mounted from the host

  • a more familiar Compose-based update routine

  • a cleaner base for later reverse proxying or container-focused automation

If your only goal is "get OpenClaw running as fast as possible," the native installer is still simpler.

What persists in this setup

The official Docker flow bind-mounts the important OpenClaw state back to the Ubuntu host:

  • the config directory for openclaw.json

  • the workspace directory

  • the auth-profile secret directory

  • the OpenClaw .env used for runtime secrets such as the Gateway token

You can also persist /home/node with OPENCLAW_HOME_VOLUME so upgrades do not wipe state that lives in the OpenClaw home directory. That matters if you later install extra tools inside the container, including Claude Code.

Before you start

This guide assumes:

  • Ubuntu 24.04 LTS

  • Docker Engine already installed

  • the Docker Compose plugin available as docker compose

  • a user account with sudo

  • SSH access to the server

  • a model-provider API key or another supported auth method ready for onboarding

  • a normal user account that can talk to Docker without sudo

If Docker is not ready yet, use How to Install Docker on Ubuntu and Run Your First Container and Docker Compose for Self-Hosted Apps: A Beginner-Friendly Guide before you continue.

Step 1: Connect to the server

SSH into the Ubuntu host from your local machine.

ssh your-user@your-server-ip

Step 2: Verify Docker access before you run the OpenClaw setup

From the server shell, make sure your normal user can talk to Docker without sudo.

docker ps

If that prints a permission error for /var/run/docker.sock, add your user to the docker group.

sudo usermod -aG docker "$USER"

The cleanest fix is to disconnect and SSH back in so your new group membership is picked up automatically. If you want a quicker in-place refresh for the current shell, run:

newgrp docker

Then verify Docker access again:

docker ps

If newgrp docker does not behave the way you want in your current session, just reconnect over SSH and rerun docker ps.

Step 3: Install Git if it is missing

The official Docker flow starts from the OpenClaw repository, so first make sure git is available.

git --version

If Ubuntu says the command is missing, install it.

sudo apt update
sudo apt install -y git

Step 4: Clone OpenClaw into /opt

Create a predictable working location for the stack.

sudo mkdir -p /opt/openclaw

Give your normal user ownership of that directory.

sudo chown "$USER":"$USER" /opt/openclaw

Move into it.

cd /opt/openclaw

Clone the repository.

git clone https://github.com/openclaw/openclaw.git

Enter the project directory.

cd openclaw

Step 5: Tell the setup script to use the official image and a persistent home volume

The Docker docs support either a locally built image or an official prebuilt image from GHCR. For a beginner VPS setup, I prefer the official image because it avoids an unnecessary local build on the first day.

Export the image choice.

export OPENCLAW_IMAGE="ghcr.io/openclaw/openclaw:latest"

Export a named volume for /home/node persistence.

export OPENCLAW_HOME_VOLUME="openclaw_home"

That extra volume is easy to skip, but it helps later. If you add container-side tools after the first install, keeping /home/node persistent makes upgrades much less annoying.

Step 6: Run the official Docker setup script

Start the official setup flow from your normal user shell.

./scripts/docker/setup.sh

Do not switch straight to sudo ./scripts/docker/setup.sh just to get around Docker socket permissions. If you do that, sudo can drop OPENCLAW_IMAGE and OPENCLAW_HOME_VOLUME, which makes the script fall back to openclaw:local, and it can also change HOME to /root, which makes OpenClaw read and write config under /root/.openclaw instead of your user profile.

If you absolutely must run the setup through sudo, preserve the variables and force your real home directory explicitly:

sudo env \
  HOME="$HOME" \
  OPENCLAW_IMAGE="$OPENCLAW_IMAGE" \
  OPENCLAW_HOME_VOLUME="$OPENCLAW_HOME_VOLUME" \
  ./scripts/docker/setup.sh

The script handles the parts that are easy to get wrong by hand:

  • onboarding prompts

  • Gateway token generation and .env creation

  • auth-profile secret directory setup

  • Docker Compose startup

Step 7: Check that the containers are up

Confirm the Compose services are running.

docker compose ps

You should see the Gateway container up, and the health column should settle into a healthy state after startup.

For a quick liveness check from the host, hit the built-in endpoint.

curl -fsS http://127.0.0.1:18789/healthz

Then confirm readiness too.

curl -fsS http://127.0.0.1:18789/readyz

If either check fails, look at the logs before changing config.

docker compose logs --tail=100 openclaw-gateway

Step 8: Open the Control UI safely from your own computer

On a public VPS, I would not rush to expose the Gateway directly on day one. Tunnel to the host over SSH first.

From your local machine, open a tunnel back to the server:

ssh -N -L 18789:127.0.0.1:18789 your-user@your-server-ip

Then open this in your local browser:

http://127.0.0.1:18789/

When the browser shows Auth required, copy the token from the project .env file on the server and paste it into the prompt.

grep '^OPENCLAW_GATEWAY_TOKEN=' .env

Copy only the value after =. The setup script normally writes this token during onboarding, so in the Docker flow that .env value is the first place to check.

If the token is missing from .env, check the running gateway container:

docker compose exec openclaw-gateway printenv OPENCLAW_GATEWAY_TOKEN

If that is also empty, generate a fresh token inside the containerized setup instead of falling back to the host-native CLI flow:

docker compose exec openclaw-gateway node dist/index.js doctor --generate-gateway-token

For this Docker workflow, prefer the SSH-tunnel URL above instead of docker compose run --rm openclaw-cli dashboard --no-open. That CLI helper can fall back to host-daemon readiness checks and may try to install a native systemd-managed gateway, which is the wrong path inside the containerized setup.

If you want to confirm the containerized Gateway is responding before opening the browser, use a direct HTTP check from the server instead:

curl -fsS http://127.0.0.1:18789/healthz

Step 9: Approve the browser device if pairing is still pending

If the dashboard shows a pairing request, list pending devices from the server.

docker compose run --rm openclaw-cli devices list

Approve the request with the ID you see.

docker compose run --rm openclaw-cli devices approve your-request-id

After that, refresh the browser and send a simple test prompt.

Host-side model runtimes need a Docker-aware URL

One Docker gotcha is worth calling out early: 127.0.0.1 inside the container is not your Ubuntu host. If you plan to point OpenClaw at Ollama or LM Studio running on the host later, use host.docker.internal instead.

Examples from the docs:

  • Ollama on the host: http://host.docker.internal:11434

  • LM Studio on the host: http://host.docker.internal:1234

That one detail saves a lot of pointless troubleshooting.

Safe update routine for this Docker setup

The OpenClaw Docker docs note that the setup script rewrites the project .env from your current shell and its defaults. Before rerunning it on an existing install, reload the saved values first.

Go back to the project directory if needed.

cd /opt/openclaw/openclaw

Load the current Docker-side variables into your shell.

set -a && . ./.env && set +a

Reassert the persistent home volume if it is not already in the file.

export OPENCLAW_HOME_VOLUME="${OPENCLAW_HOME_VOLUME:-openclaw_home}"

Pull the latest repository changes.

git pull

Rerun the setup script.

./scripts/docker/setup.sh

Finish with a quick health check.

docker compose ps

If you want shorter day-to-day commands later, OpenClaw's optional ClawDock helpers can wrap the usual Compose tasks. I would still get comfortable with the plain commands first so you know what the stack is doing under the hood.

Where to go next

Once the Docker deployment is working, these are the next guides I would keep nearby:

That is a good order to follow. Get the containerized Gateway stable first, tune the config second, and worry about public access or more advanced integrations after that.

Frequently Asked Questions

Is Docker Compose the best first way to run OpenClaw?
Not always. I still prefer the normal installer for the simplest first run, but Docker Compose is a better fit when you want cleaner isolation, container-style operations, and easier rollback habits on a VPS.
What actually stays persistent in the Docker setup?
The bundled Compose setup bind-mounts the OpenClaw config directory, workspace directory, and auth-profile secret directory from the host, and you can also persist /home/node with OPENCLAW_HOME_VOLUME so updates do not wipe container-side state such as Claude Code installs.
Can OpenClaw in Docker talk to a model runtime on the host?
Yes. The Docker docs use host.docker.internal for host-side runtimes such as Ollama or LM Studio because 127.0.0.1 inside the container points at the container itself, not your Ubuntu host.
share

Was this article helpful?

Let me know so I can keep improving.

Related articles

🤖
AI & LLMs
How to Install OpenClaw on Ubuntu and Complete Your First Setup
Install OpenClaw on Ubuntu, run the recommended onboarding flow, verify the Gateway, and open the Control UI safely on a VPS without exposing it carelessly on day one.
🤖
AI & LLMs
OpenClaw Troubleshooting Guide: Fix Common Setup and Runtime Problems
Use the right OpenClaw checks in the right order so you can fix config failures, broken updates, remote-access issues, and silent channels without random guesswork.
🎬
Media Servers
Install Jellyfin with Docker Compose on Ubuntu 24.04 LTS
Install Jellyfin with Docker Compose on Ubuntu 24.04 LTS, keep your media library mounted cleanly, and finish the first web setup without turning movie night into a troubleshooting session.
🔒
Security & Firewalls
Set Up a WireGuard VPN on Ubuntu 24.04 LTS
Set up a WireGuard VPN on Ubuntu 24.04 LTS, create a server and client profile, and route your traffic through a fast self-hosted tunnel.