Hetzner
Run OpenClaw Gateway 24/7 on a cheap Hetzner VPS (Docker) with durable state and baked-in binaries
Goal
Run a persistent OpenClaw Gateway on a Hetzner VPS using Docker, with durable state, baked-in binaries, and safe restart behavior.
If you want "OpenClaw 24/7 for ~$5", this is simplest reliable setup.
Hetzner pricing changes; pick the smallest Debian/Ubuntu VPS and scale up if you hit OOMs.
What are we doing (simple terms)?
- Rent a small Linux server (Hetzner VPS)
- Install Docker (isolated app runtime)
- Start OpenClaw Gateway in Docker
- Persist ''~/.openclaw'' + ''~/.openclaw/workspace'' on host (survives restarts/rebuilds)
- Access Control UI from your laptop via an SSH tunnel
The Gateway can be accessed via:
- SSH port forwarding from your laptop
- Direct port exposure if you manage firewalling and tokens yourself
This guide assumes Ubuntu or Debian on Hetzner.
If you are on another Linux VPS, map packages accordingly.
For generic Docker flow, see ''Docker''.
What you need
- Hetzner VPS with root access
- SSH access from your laptop
- Basic comfort with SSH + copy/paste
- ~20 minutes
- Docker and Docker Compose
- Model auth credentials
- Optional provider credentials
- WhatsApp QR
- Telegram bot token
- Gmail OAuth
2) Install Docker (on VPS)
apt-get update apt-get install -y git curl ca-certificates curl -fsSL https://get.docker.com | sh
Verify:
docker --version docker compose version
4) Create persistent host directories
Docker containers are ephemeral.
All long-lived state must live on host.
mkdir -p /root/.openclaw mkdir -p /root/.openclaw/workspace chown -R 1000:1000 /root/.openclaw chown -R 1000:1000 /root/.openclaw/workspace
6) Docker Compose configuration
Create or update ''docker-compose.yml''.
services:
openclaw-gateway:
image: ${OPENCLAW_IMAGE}
build: .
restart: unless-stopped
env_file:
- .env
environment:
- HOME=/home/node
- NODE_ENV=production
- TERM=xterm-256color
- OPENCLAW_GATEWAY_BIND=${OPENCLAW_GATEWAY_BIND}
- OPENCLAW_GATEWAY_PORT=${OPENCLAW_GATEWAY_PORT}
- OPENCLAW_GATEWAY_TOKEN=${OPENCLAW_GATEWAY_TOKEN}
- GOG_KEYRING_PASSWORD=${GOG_KEYRING_PASSWORD}
- XDG_CONFIG_HOME=${XDG_CONFIG_HOME}
- PATH=/home/linuxbrew/.linuxbrew/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
volumes:
- ${OPENCLAW_CONFIG_DIR}:/home/node/.openclaw
- ${OPENCLAW_WORKSPACE_DIR}:/home/node/.openclaw/workspace
ports:
# Recommended: keep Gateway loopback-only on VPS; access via SSH tunnel.
# To expose it publicly, remove `127.0.0.1:` prefix and firewall accordingly.
- "127.0.0.1:${OPENCLAW_GATEWAY_PORT}:18789"
# Optional: only if you run iOS/Android nodes against this VPS and need Canvas host.
# If you expose this publicly, read /gateway/security and firewall accordingly.
# - "18793:18793"
command:
[
"node",
"dist/index.js",
"gateway",
"--bind",
"${OPENCLAW_GATEWAY_BIND}",
"--port",
"${OPENCLAW_GATEWAY_PORT}",
]8) Build and launch
docker compose build docker compose up -d openclaw-gateway
Verify binaries:
docker compose exec openclaw-gateway which gog docker compose exec openclaw-gateway which goplaces docker compose exec openclaw-gateway which wacli
Expected output:
/usr/local/bin/gog /usr/local/bin/goplaces /usr/local/bin/wacli
What persists where (source of truth)
OpenClaw runs in Docker, but Docker is not source of truth.
All long-lived state must survive restarts, rebuilds, and reboots.
| Component | Location | Persistence mechanism | Notes |
| Gateway config | ''/home/node/.openclaw/'' | Host volume mount | Includes ''openclaw.json'', tokens |
| Model auth profiles | ''/home/node/.openclaw/'' | Host volume mount | OAuth tokens, API keys |
| Skill configs | ''/home/node/.openclaw/skills/'' | Host volume mount | Skill-level state |
| Agent workspace | ''/home/node/.openclaw/workspace/'' | Host volume mount | Code and agent artifacts |
| WhatsApp session | ''/home/node/.openclaw/'' | Host volume mount | Preserves QR login |
| Gmail keyring | ''/home/node/.openclaw/'' | Host volume + password | Requires ''GOG_KEYRING_PASSWORD'' |
| External binaries | ''/usr/local/bin/'' | Docker image | Must be baked at build time |
| Node runtime | Container filesystem | Docker image | Rebuilt every image build |
| OS packages | Container filesystem | Docker image | Do not install at runtime |
| Docker container | Ephemeral | Restartable | Safe to destroy |