Running OpenClaw in Docker: images, volumes, and the port-binding trap
The official Docker setup, what must be volume-mounted for your agent to survive, and the default that quietly puts the Gateway on your network.
OpenClaw ships official Docker images (ghcr.io/openclaw/openclaw) and a Compose-based setup. Three things decide whether your containerized agent thrives: mount the state directories as volumes (or your agent’s memory dies with the container), pin a version tag instead of latest, and check what the Gateway port is bound to — the Docker setup’s default bind is lan, which is broader than the loopback default you may expect from a native install.
The official images
Images are published to GitHub Container Registry, with a Docker Hub mirror:
ghcr.io/openclaw/openclaw:<version>— pinned release, the right choice for anything you intend to keep. Tags likelatestandmainexist, but a long-running stateful agent shouldn’t follow a moving tag — surprise upgrades are how a working setup becomes a mystery, and the security audit itself flags unpinned installs.- The
-browservariants ship Chromium baked in — get this one if your agent will browse or do anything screen-shaped, rather than installing a browser into a running container.
Volumes: the difference between an agent and an amnesiac
Inside the container, OpenClaw’s state lives under /home/node/.openclaw (config, sessions, workspace) and /home/node/.config/openclaw (auth secrets). The official Compose file mounts both from the host — the docs put it plainly: those paths survive container replacement. Everything rides on that mount: your agent’s whole identity is that directory. Get it right and containers become disposable — you can recreate, upgrade, and reboot and the agent comes back itself; we’ve verified that on our own pods through full server reboots. Get it wrong and the first docker compose down erases your agent’s mind.
The port-binding trap
The one setting worth double-checking before anything else: the official Docker setup defaults the Gateway bind to lan (so the host can reach the dashboard through Docker’s port publishing), and the Compose file publishes port 18789. On a laptop behind a home router that’s merely worth knowing. On a VPS with a public address, a published Gateway port is the exact exposure OpenClaw’s own security docs say must never happen — an unauthenticated Gateway is remote control of a machine that can run commands. On any internet-facing host: bind to loopback (OPENCLAW_GATEWAY_BIND=loopback), publish the port to 127.0.0.1 only or not at all, and run openclaw security audit (inside the container, via docker compose exec) after every networking change.
Setup, and the fine print worth knowing
The repo ships a setup script (./scripts/docker/setup.sh) that prompts for provider keys, generates a Gateway token into .env, and starts Compose; there’s also a manual flow (docker compose run the onboarding, then docker compose up -d). Three facts from the official docs that save real debugging time:
- Building the image needs ~2 GB of RAM — on a 1 GB host the build gets OOM-killed with exit code 137. Use the prebuilt images on small machines.
127.0.0.1inside the container is the container, not your host — local model runners like Ollama on the host are reached viahost.docker.internal.- The dashboard wants its token — the setup script writes it to
.env; you paste it athttp://127.0.0.1:18789/on first visit.
Docker is exactly how we run OpenClaw on Everpod pods — pinned image, volume-mounted state, loopback-only Gateway, audited after provisioning. If you’d rather have that arrive assembled, that’s the product; if you’re building it yourself, the safe-hosting checklist is the standard worth holding your setup to.