OpenClaw op een VPS: veilige deployment met Docker en Tailscale

Implementeer OpenClaw op een Linux VPS met Docker Compose, bind poorten alleen aan localhost en krijg veilig toegang via SSH-tunnels of Tailscale Serve.

OpenClaw op een VPS: veilige deployment met Docker en Tailscale
Ook beschikbaar in het English, Deutsch, Français, Español.

OpenClaw op een VPS is vooral een ops-probleem, geen AI-probleem. Je wilt één altijd-aan Gateway die je state, sessies en kanalen beheert — maar je wilt niet dat die Gateway bereikbaar is vanaf het publieke internet.

Het patroon: draai OpenClaw in Docker, publiceer de poorten alleen op 127.0.0.1, en benader het via een SSH-tunnel of een Tailscale tailnet.

Waarom de standaardinstellingen je gaan bijten

De Gateway van OpenClaw is één langlopende service. Het regelt routing, de Control UI, WebSocket RPC en HTTP API's via één gemultiplexte poort — standaard 18789. De niet-Docker-installatie bindt standaard aan loopback. Auth is standaard vereist via token of wachtwoord.

De standaardinstellingen van Docker zijn minder vergevingsgezind. Het docker-setup.sh-script zet OPENCLAW_GATEWAY_BIND=lan zodat host-gepubliceerde poorten daadwerkelijk werken. Als je het op loopback zet, kunnen alleen processen binnen de netwerknamespace van de container verbinden — je host-gepubliceerde poort valt stil.

Het veilige compromis: houd OPENCLAW_GATEWAY_BIND=lan binnen de container, maar bind de host-side port publishing aan 127.0.0.1. Niets raakt 0.0.0.0, en de containernetwerking blijft werken.

Docker port publishing omzeilt ufw en firewalld. Ga ervan uit dat je firewall niet de enige controle is.

Richt de VPS in

De commando's hieronder gaan uit van Ubuntu 24.04 LTS met root SSH-toegang. Een Hetzner CX22 voor €4,85/maand met €10 starttegoed kan dit prima aan — het is waar deze blog op draait.

Maak een niet-root gebruiker aan en vergrendel SSH:

adduser openclaw
usermod -aG sudo openclaw
mkdir -p /home/openclaw/.ssh
chmod 700 /home/openclaw/.ssh

# Paste your public key
nano /home/openclaw/.ssh/authorized_keys

chmod 600 /home/openclaw/.ssh/authorized_keys
chown -R openclaw:openclaw /home/openclaw/.ssh

Harden SSH met een drop-in bestand:

nano /etc/ssh/sshd_config.d/99-openclaw-hardening.conf
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
AllowUsers openclaw
sshd -t
systemctl reload ssh

Stel ufw in als baseline. Dit vervangt niet de correcte Docker port binding — Docker prikt er zonder problemen doorheen.

apt update && apt upgrade -y
apt install -y ufw git curl ca-certificates

ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw enable

Installeer Docker Engine

Gebruik Docker's officiële apt repo zodat je docker-compose-plugin en daadwerkelijke updates krijgt:

sudo apt remove -y \
  $(dpkg --get-selections docker.io docker-compose docker-compose-v2 \
    docker-doc podman-docker containerd runc 2>/dev/null | cut -f1) \
  || true

sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

sudo tee /etc/apt/sources.list.d/docker.sources >/dev/null <<'EOF'
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker

Je gebruiker toevoegen aan de docker-groep geeft root-equivalente rechten. Op een VPS is sudo docker ... meestal de juiste afweging.

Deploy OpenClaw met localhost-only poorten

Clone de repo en werk vanuit de root:

sudo -iu openclaw
mkdir -p ~/src && cd ~/src
git clone https://github.com/openclaw/openclaw.git
cd openclaw

Maak een .env aan die je paden vastlegt en de officiële image van GitHub Container Registry gebruikt:

# .env
OPENCLAW_CONFIG_DIR=/home/openclaw/.openclaw
OPENCLAW_WORKSPACE_DIR=/home/openclaw/.openclaw/workspace
OPENCLAW_IMAGE=ghcr.io/openclaw/openclaw:latest
OPENCLAW_GATEWAY_BIND=lan
OPENCLAW_GATEWAY_PORT=18789
OPENCLAW_BRIDGE_PORT=18790
OPENCLAW_GATEWAY_TOKEN=

Nu de beveiligingsstap die ertoe doet. Maak docker-compose.override.yml aan om gepubliceerde poorten alleen aan 127.0.0.1 te binden:

# docker-compose.override.yml
services:
  openclaw-gateway:
    ports:
      - "127.0.0.1:18789:18789"
      - "127.0.0.1:18790:18790"

Zonder het 127.0.0.1:-prefix bindt Compose aan alle interfaces. Dat is 0.0.0.0. Dat is het internet.

Pull, onboard en start:

docker compose pull

docker compose run --rm openclaw-cli onboard

docker compose -f docker-compose.yml -f docker-compose.override.yml \
  up -d openclaw-gateway

Sanity-check:

docker compose ps

docker compose run -T --rm openclaw-cli gateway probe

De -T-vlag voorkomt pseudo-TTY-ruis — handig voor scripts en CI.

Op dit punt werkt http://127.0.0.1:18789 op de VPS zelf. Het is onbereikbaar van elke andere plek. Dat is het doel.

Overleef reboots met systemd

sudo nano /etc/systemd/system/openclaw-compose.service
[Unit]
Description=OpenClaw (Docker Compose)
Requires=docker.service
After=docker.service

[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/home/openclaw/src/openclaw
ExecStart=/usr/bin/docker compose \
  -f docker-compose.yml -f docker-compose.override.yml up -d
ExecStop=/usr/bin/docker compose \
  -f docker-compose.yml -f docker-compose.override.yml down
TimeoutStartSec=0

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now openclaw-compose.service

Toegang op afstand: SSH-tunnel of Tailscale

Je hebt een Gateway gebonden aan loopback op een VPS. Je moet deze bereiken vanaf je laptop. Twee opties, verschillende afwegingen.

Methode Wat is publiek Wrijving Beste voor
SSH-tunnel Poort 22 Sessie moet actief blijven; onhandig op mobiel Eén of twee machines, geen extra afhankelijkheden
Tailscale Serve Niets Extra daemon, maar daarna hands-off Meerdere apparaten, altijd-aan toegang
Directe blootstelling Een HTTPS-endpoint TLS, auth, reverse proxy, patching Alleen als je echt publieke toegang nodig hebt

SSH-tunnel

Vanaf je laptop:

ssh -N -L 18789:127.0.0.1:18789 openclaw@203.0.113.10

Open vervolgens http://127.0.0.1:18789 lokaal.

Voeg SSH keepalives toe in je lokale ~/.ssh/config als je wilt dat de tunnel de slaapstand van je laptop overleeft.

Tailscale Serve

Installeer Tailscale op de VPS:

curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

Stel OpenClaw beschikbaar binnen je tailnet met automatische TLS:

sudo tailscale serve --bg --https=443 localhost:18789
sudo tailscale serve status

Tailscale Serve reverse-proxyt een lokale poort naar je tailnet met automatisch geproviseerde HTTPS-certificaten. TLS termineert bij tailscaled. Geen publieke poorten, geen certificaatbeheer.

Als je ook de publieke SSH-poort volledig wilt sluiten, kan Tailscale SSH authenticatie en autorisatie afhandelen voor SSH-verbindingen binnen je tailnet.

Hardeningchecklist

Het deel dat de meeste handleidingen overslaan.

Docker en container

De standaard image van OpenClaw draait als de niet-root node-gebruiker. Begin daar en voeg toe:

Controle Waar Wat het je oplevert
Bind poorten aan 127.0.0.1 Compose ports Geen 0.0.0.0-blootstelling, geen firewall-bypass-verrassingen
cap_drop: [ALL] Compose Verwijdert kernel capabilities die je niet nodig hebt
no-new-privileges:true Compose security_opt Blokkeert privilege-escalatie via setuid-binaries
Standaard seccomp-profiel Docker standaard Syscall-allowlist; overschrijf niet zonder reden
Standaard AppArmor-profiel Docker standaard docker-default-profiel is redelijk beschermend

De openclaw-cli-container deelt een netwerknamespace met de gateway (network_mode: "service:openclaw-gateway"). Behandel het als een gedeelde trust boundary, niet als isolatie.

SSH

Houd PasswordAuthentication no, PermitRootLogin no en AllowUsers vergrendeld op het ene account dat toegang nodig heeft. Dat is het minimum.

Tailscale

Gebruik tailnet access controls om te beperken welke gebruikers en apparaten de VPS kunnen bereiken. ACL's of grants — beide werken, maar handhaaf iets. Behandel Tailscale als een identiteitslaag, niet als een magisch schild.

Skills en supply chain

Als je third-party skills installeert, draai je third-party code binnen een tool-capable agent. Er zijn geloofwaardige berichten over kwaadaardige OpenClaw-skills die malware verspreiden en secrets stelen.

De enige regel: installeer niets dat je niet als normaal programma op dezelfde machine zou draaien.

Probleemoplossing

Control UI werkt op de VPS maar niet op afstand. Correct. Het is gebonden aan 127.0.0.1. Je hebt SSH of Tailscale nodig — dat is het hele punt.

OPENCLAW_GATEWAY_BIND=loopback in Docker gezet, host-poort werkt niet meer. Verwacht. Loopback binnen de containernamespace is niet hetzelfde als loopback op de host. Gebruik lan in de container, beperk de blootstelling met 127.0.0.1 in Compose port mappings.

"Disconnected (1008): pairing required" of "unauthorized" in de browser.

docker compose run --rm openclaw-cli dashboard --no-open
docker compose run --rm openclaw-cli devices list
docker compose run --rm openclaw-cli devices approve <requestId>

Gepubliceerde poorten omzeilen UFW. Ja. Docker manipuleert iptables rechtstreeks. Binden aan 127.0.0.1 in Compose is de oplossing, niet een firewallregel.

Gateway weigert te starten. OpenClaw hanteert strikte configuratievalidatie. Non-loopback binding zonder auth is een veelvoorkomende foutmodus.

docker compose run -T --rm openclaw-cli doctor
docker compose logs --no-log-prefix --tail=200 openclaw-gateway

Welke poort moet je forwarden? 18789. Dat is de standaard gemultiplexte poort van de Gateway voor de Control UI en API's.

Wat moet je back-uppen? De hostpaden die gemapped zijn naar config en workspace — meestal ~/.openclaw/ en ~/.openclaw/workspace. Vertrouw niet op de schrijfbare laag van de container.

AI-pointer opmerking

Als je deze setup debugt met een AI-assistent, plak de URL van dit bericht in het gesprek. Het geeft het model de exacte stackcontext: Docker Compose met localhost-only port binding, lan vs loopback Gateway bind in Docker, en toegang via ssh -L of tailscale serve.


Waar dit te draaien

Een saaie VPS is de juiste keuze. We draaien vergelijkbare always-on Docker-stacks op Hetzner — CX22 voor €4,85/maand met €10 starttegoed. Het doet wat je nodig hebt en niets wat je niet nodig hebt.

Als je liever niet om 1 uur 's nachts Docker port bindings debugt, biedt xCloud managed OpenClaw hosting. Je betaalt meer en slaapt beter.

Als je een tweede VPS-optie wilt of providers vergelijkt, geeft Vultr $35 aan verwijzingstegoed en heeft een brede lijst met regio's.

(Affiliatelinks — we ontvangen een kleine vergoeding als je je aanmeldt, zonder extra kosten voor jou.)