OpenClaw auf einem VPS: sichere Bereitstellung mit Docker und Tailscale

Stellen Sie OpenClaw auf einem Linux-VPS mit Docker Compose bereit, binden Sie Ports nur an localhost und greifen Sie sicher über SSH-Tunnel oder Tailscale Serve zu.

OpenClaw auf einem VPS: sichere Bereitstellung mit Docker und Tailscale
Auch verfügbar auf English, Français, Español, Nederlands.

OpenClaw auf einem VPS ist hauptsächlich ein Ops-Problem, kein AI-Problem. Du willst ein einzelnes, dauerhaft laufendes Gateway, das deinen State, deine Sessions und Channels verwaltet — aber dieses Gateway soll nicht aus dem öffentlichen Internet erreichbar sein.

Das Muster: OpenClaw in Docker betreiben, die Ports nur auf 127.0.0.1 veröffentlichen und dann per SSH-Tunnel oder über ein Tailscale-Tailnet darauf zugreifen.

Warum die Standardeinstellungen dir Probleme machen

Das Gateway von OpenClaw ist ein einzelner, dauerhaft laufender Service. Es übernimmt Routing, die Control UI, WebSocket-RPC und HTTP-APIs über einen einzigen gemultiplexten Port — standardmäßig 18789. Die Nicht-Docker-Installation bindet standardmäßig an Loopback. Authentifizierung ist ab Werk per Token oder Passwort erforderlich.

Die Docker-Standardeinstellungen sind weniger nachsichtig. Das docker-setup.sh-Skript setzt OPENCLAW_GATEWAY_BIND=lan, damit die vom Host veröffentlichten Ports tatsächlich funktionieren. Setzt du es auf loopback, können nur Prozesse innerhalb des Container-Netzwerk-Namespaces eine Verbindung herstellen — dein host-seitig veröffentlichter Port ist tot.

Der sichere Kompromiss: OPENCLAW_GATEWAY_BIND=lan innerhalb des Containers beibehalten, aber das host-seitige Port-Publishing auf 127.0.0.1 binden. Nichts trifft auf 0.0.0.0, und das Container-Networking funktioniert weiterhin.

Docker-Port-Publishing umgeht ufw und firewalld. Geh davon aus, dass deine Firewall nicht die einzige Schutzmaßnahme ist.

VPS provisionieren

Die folgenden Befehle setzen Ubuntu 24.04 LTS mit Root-SSH-Zugang voraus. Ein Hetzner CX22 für 4,85 €/Monat mit 10 € Startguthaben reicht dafür völlig aus — darauf läuft auch dieser Blog.

Erstelle einen Nicht-Root-Benutzer und sichere SSH ab:

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

SSH härten mit einer Drop-in-Datei:

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

Richte ufw als Baseline ein. Das ersetzt nicht die korrekte Docker-Port-Bindung — Docker schlägt problemlos ein Loch hindurch.

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

Docker Engine installieren

Nutze Dockers offizielles Apt-Repository, damit du docker-compose-plugin und echte Updates bekommst:

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

Deinen Benutzer zur docker-Gruppe hinzuzufügen gewährt Root-äquivalente Rechte. Auf einem VPS ist sudo docker ... meistens der richtige Kompromiss.

OpenClaw mit localhost-only Ports deployen

Klone das Repository und arbeite aus seinem Root-Verzeichnis:

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

Erstelle eine .env, die deine Pfade festlegt und das offizielle Image aus der GitHub Container Registry nutzt:

# .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=

Jetzt kommt der Sicherheitsschritt, der wirklich zählt. Erstelle docker-compose.override.yml, um die veröffentlichten Ports nur an 127.0.0.1 zu binden:

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

Ohne das 127.0.0.1:-Präfix bindet Compose an alle Interfaces. Das ist 0.0.0.0. Das ist das Internet.

Pullen, Onboarding durchführen und starten:

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

Plausibilitätsprüfung:

docker compose ps

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

Das -T-Flag vermeidet Pseudo-TTY-Rauschen — nützlich für Skripte und CI.

An diesem Punkt funktioniert http://127.0.0.1:18789 auf dem VPS selbst. Von überall sonst ist es nicht erreichbar. Genau das ist das Ziel.

Neustarts mit systemd überleben

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

Remote-Zugriff: SSH-Tunnel oder Tailscale

Du hast ein Gateway, das auf Loopback eines VPS gebunden ist. Du musst von deinem Laptop darauf zugreifen. Zwei Optionen mit unterschiedlichen Kompromissen.

Methode Was öffentlich ist Aufwand Am besten für
SSH-Tunnel Port 22 Session muss am Leben bleiben; umständlich auf Mobilgeräten Ein oder zwei Rechner, keine zusätzlichen Abhängigkeiten
Tailscale Serve Nichts Zusätzlicher Daemon, danach aber wartungsfrei Mehrere Geräte, Always-on-Zugriff
Direkte Exposition Ein HTTPS-Endpunkt TLS, Auth, Reverse Proxy, Patching Nur wenn du wirklich öffentlichen Zugriff brauchst

SSH-Tunnel

Von deinem Laptop:

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

Dann öffne http://127.0.0.1:18789 lokal.

Füge SSH-Keepalives in deiner lokalen ~/.ssh/config hinzu, wenn der Tunnel den Laptop-Sleep überleben soll.

Tailscale Serve

Tailscale auf dem VPS installieren:

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

OpenClaw innerhalb deines Tailnets mit automatischem TLS bereitstellen:

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

Tailscale Serve fungiert als Reverse Proxy für einen lokalen Port in dein Tailnet — mit automatisch provisionierten HTTPS-Zertifikaten. TLS terminiert bei tailscaled. Keine öffentlichen Ports, kein Zertifikatsmanagement.

Wenn du auch den öffentlichen SSH-Port komplett loswerden willst: Tailscale SSH kann Authentifizierung und Autorisierung für SSH-Verbindungen innerhalb deines Tailnets übernehmen.

Hardening-Checkliste

Der Teil, den die meisten Anleitungen überspringen.

Docker und Container

Das Standard-Image von OpenClaw läuft als Nicht-Root-Benutzer node. Starte damit und ergänze:

Maßnahme Wo Was es bringt
Ports auf 127.0.0.1 binden Compose ports Keine 0.0.0.0-Exposition, keine Firewall-Bypass-Überraschungen
cap_drop: [ALL] Compose Entfernt Kernel-Capabilities, die du nicht brauchst
no-new-privileges:true Compose security_opt Blockiert Privilege Escalation über setuid-Binaries
Standard-Seccomp-Profil Docker-Standard Syscall-Allowlist; nicht ohne Grund überschreiben
Standard-AppArmor-Profil Docker-Standard Das docker-default-Profil bietet moderaten Schutz

Der openclaw-cli-Container teilt sich einen Netzwerk-Namespace mit dem Gateway (network_mode: "service:openclaw-gateway"). Betrachte das als gemeinsame Trust-Boundary, nicht als Isolation.

SSH

Behalte PasswordAuthentication no, PermitRootLogin no und AllowUsers beschränkt auf den einen Account, der Zugriff braucht. Das ist das Minimum.

Tailscale

Nutze Tailnet-Access-Controls, um einzuschränken, welche Benutzer und Geräte den VPS erreichen können. ACLs oder Grants — beides funktioniert, aber setze etwas durch. Betrachte Tailscale als Identity-Layer, nicht als magischen Schutzschild.

Skills und Supply Chain

Wenn du Third-Party-Skills installierst, führst du Drittanbieter-Code innerhalb eines tool-fähigen Agenten aus. Es gibt glaubwürdige Berichte über bösartige OpenClaw-Skills, die Malware verbreiten und Secrets stehlen.

Die einzige Regel: Installiere nichts, was du nicht auch als normales Programm auf derselben Maschine ausführen würdest.

Fehlerbehebung

Control UI funktioniert auf dem VPS, aber nicht remote. Korrekt. Sie ist an 127.0.0.1 gebunden. Du brauchst SSH oder Tailscale — genau das ist der Sinn der Sache.

OPENCLAW_GATEWAY_BIND=loopback in Docker gesetzt, Host-Port funktioniert nicht mehr. Erwartetes Verhalten. Loopback innerhalb des Container-Namespaces ist nicht dasselbe wie Loopback auf dem Host. Nutze lan im Container und beschränke die Exposition mit 127.0.0.1 in den Compose-Port-Mappings.

"Disconnected (1008): pairing required" oder "unauthorized" im 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>

Veröffentlichte Ports umgehen UFW. Ja. Docker manipuliert iptables direkt. Die Bindung an 127.0.0.1 in Compose ist die Lösung, nicht eine Firewall-Regel.

Gateway startet nicht. OpenClaw erzwingt strikte Config-Validierung. Nicht-Loopback-Binding ohne Auth ist ein häufiger Fehlerfall.

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

Welchen Port muss ich weiterleiten? 18789. Das ist der standardmäßige gemultiplexte Port des Gateways für die Control UI und APIs.

Was sollte ich sichern? Die Host-Pfade, die auf Config und Workspace gemappt sind — typischerweise ~/.openclaw/ und ~/.openclaw/workspace. Verlass dich nicht auf den beschreibbaren Layer des Containers.

KI-Hinweis

Wenn du dieses Setup mit einem KI-Assistenten debuggst, füge die URL dieses Beitrags in die Konversation ein. Das gibt dem Modell den exakten Stack-Kontext: Docker Compose mit localhost-only Port-Binding, lan vs. loopback Gateway-Bind in Docker und Zugriff über ssh -L oder tailscale serve.


Wo das Ganze betreiben

Ein langweiliger VPS ist die richtige Wahl. Ich betreibe ähnliche Always-on-Docker-Stacks auf Hetzner — CX22 für 4,85 €/Monat mit 10 € Startguthaben. Er tut, was du brauchst, und nichts, was du nicht brauchst.

Wenn du lieber nicht um 1 Uhr nachts Docker-Port-Bindings debuggen willst, bietet xCloud Managed OpenClaw Hosting. Du zahlst mehr und schläfst besser.

Wenn du eine zweite VPS-Option willst oder Anbieter vergleichst: Vultr bietet 35 $ Referral-Guthaben und hat eine breite Regionsliste.

(Affiliate-Links — ich bekomme eine kleine Provision, wenn du dich anmeldest, ohne Zusatzkosten für dich.)