docs/install/hetzner.md
Run a persistent OpenClaw Gateway on a Hetzner VPS using Docker, with durable state, baked-in binaries, and safe restart behavior.
Hetzner pricing changes; pick the smallest Debian/Ubuntu VPS that fits and scale up if you hit OOMs.
The Gateway can be accessed via SSH port forwarding from your laptop, or via direct port exposure if you manage firewalling and tokens yourself.
Security model reminder:
See Security and VPS hosting.
This guide assumes Ubuntu or Debian on Hetzner. On another Linux VPS, map packages accordingly. For the generic Docker flow, see Docker.
.env and docker-compose.ymldocker compose up -d```bash
ssh root@YOUR_VPS_IP
```
Treat the VPS as stateful, not disposable infrastructure.
Verify:
```bash
docker --version
docker compose version
```
This guide builds a custom image so any binaries you bake in survive restarts.
```bash
mkdir -p /root/.openclaw/workspace
# Set ownership to the container user (uid 1000):
chown -R 1000:1000 /root/.openclaw
```
```bash
OPENCLAW_IMAGE=openclaw:latest
OPENCLAW_GATEWAY_TOKEN=
OPENCLAW_GATEWAY_BIND=lan
OPENCLAW_GATEWAY_PORT=18789
OPENCLAW_CONFIG_DIR=/root/.openclaw
OPENCLAW_WORKSPACE_DIR=/root/.openclaw/workspace
GOG_KEYRING_PASSWORD=
XDG_CONFIG_HOME=/home/node/.openclaw
```
Set `OPENCLAW_GATEWAY_TOKEN` to manage the stable gateway token through
`.env`; otherwise configure `gateway.auth.token` before relying on clients
across restarts. If neither is set, OpenClaw uses a runtime-only token for
that startup. Generate a keyring password for `GOG_KEYRING_PASSWORD`:
```bash
openssl rand -hex 32
```
**Do not commit this file.** It holds container/runtime env such as
`OPENCLAW_GATEWAY_TOKEN`. Stored provider OAuth/API-key auth lives in the
mounted `~/.openclaw/agents/<agentId>/agent/auth-profiles.json`.
```yaml
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 the Gateway loopback-only on the VPS; access via SSH tunnel.
# To expose it publicly, remove the `127.0.0.1:` prefix and firewall accordingly.
- "127.0.0.1:${OPENCLAW_GATEWAY_PORT}:18789"
command:
[
"node",
"dist/index.js",
"gateway",
"--bind",
"${OPENCLAW_GATEWAY_BIND}",
"--port",
"${OPENCLAW_GATEWAY_PORT}",
"--allow-unconfigured",
]
```
`--allow-unconfigured` is only for bootstrap convenience, not a substitute for real gateway configuration. Still set auth (`gateway.auth.token` or password) and a safe bind mode for your deployment.
- [Bake required binaries into the image](/install/docker-vm-runtime#bake-required-binaries-into-the-image)
- [Build and launch](/install/docker-vm-runtime#build-and-launch)
- [What persists where](/install/docker-vm-runtime#what-persists-where)
- [Updates](/install/docker-vm-runtime#updates)
**Prerequisite:** ensure your VPS sshd config allows TCP forwarding. If you
hardened your SSH config, check `/etc/ssh/sshd_config` and set:
```text
AllowTcpForwarding local
```
`local` allows `ssh -L` local forwards from your laptop while blocking
remote forwards from the server. Setting it to `no` fails the tunnel with:
`channel 3: open failed: administratively prohibited: open failed`
After confirming TCP forwarding is enabled, restart the SSH service
(`systemctl restart ssh`) and run the tunnel from your laptop:
```bash
ssh -N -L 18789:127.0.0.1:18789 root@YOUR_VPS_IP
```
Open `http://127.0.0.1:18789/` and paste the configured shared secret.
This guide uses the gateway token by default; use your configured password
instead if you switched to password auth.
The shared persistence map lives in Docker VM Runtime.
For teams preferring infrastructure-as-code workflows, a community-maintained Terraform setup provides:
Repositories:
This approach complements the Docker setup above with reproducible deployments, version-controlled infrastructure, and automated disaster recovery.
<Note> Community-maintained. For issues or contributions, see the repository links above. </Note>