„Habe riesige Probleme mit meinem VPS. Installiere OpenClaw jetzt zum 3. oder 4. Mal neu.”

Diese Nachricht tauchte letzten Monat im OpenClaw Discord auf. Der Nutzer war nicht allein. Wenn Sie durch die Community-Kanäle scrollen, finden Sie Dutzende Variationen desselben Themas: Browser-Tool schlägt fehl, Agent erreicht Chromium nicht, VPS hat keinen Speicher mehr, gestern ging alles und heute nicht mehr.

Wenn Sie diesen Artikel lesen, weil Sie gerade „OpenClaw Browser funktioniert nicht VPS” gesucht haben, sind Sie hier richtig. Dieser Beitrag erklärt die fünf Dinge, die schiefgehen, warum sie auf frustrierende Weise zusammenwirken, und wie wir sie alle im OpenClaw.rocks Kubernetes Operator gelöst haben, damit Sie sich nie wieder mit Browser-Konfiguration beschäftigen müssen.

Der Fehler, den alle sehen

Die häufigste Fehlermeldung in der OpenClaw Community lautet:

Can't reach the OpenClaw browser control service
(timed out after 15000ms)

Sie erscheint auf Ubuntu, Debian, in Docker, auf Hetzner, Hostinger, GCP und überall sonst, wo OpenClaw mit Browser-Automatisierung betrieben wird. Die Gateway-Logs melden „Browser control service ready.” Aber wenn der Agent den Browser nutzen will, kommt ein Timeout.

Der Fehler ist generisch. Die Ursachen sind es nicht. Es gibt mindestens fünf verschiedene Fehlermodi, und sie sehen von außen alle identisch aus.

Fehler 1: Snap Chromium und die AppArmor-Mauer

Auf einem frischen Ubuntu 22.04+ Server liefert which chromium-browser den Pfad /usr/bin/chromium-browser. Das sieht korrekt aus. Ist es aber nicht.

Seit Ubuntu 22.04 ist das Standard-Chromium-Paket ein snap. Wenn OpenClaws Gateway dieses Binary über einen systemd-Dienst starten will, blockiert AppArmors Confinement-Schicht den Zugriff. Das snap-Paket kann keine Chrome DevTools Protocol (CDP) Debugging-Ports durch die Sandbox öffnen. Das Binary startet, scheint zu laufen, scheitert dann aber lautlos beim Öffnen des Ports, den OpenClaw benötigt.

In den Logs sehen Sie „Failed to start Chrome CDP on port 18800”, manchmal auch gar nichts. Der Browser-Prozess startet und stirbt, bevor er eine einzige Log-Zeile schreibt.

Die Lösung ist die Installation von Google Chromes .deb-Paket oder die Verwendung von Playwrights eigenständigem Chromium-Binary aus ~/.cache/ms-playwright/. Beide umgehen die snap-Sandbox. Aber die Lösung ist nicht offensichtlich. OpenClaws Browser-Erkennung durchsucht Standard-Pfade der Reihe nach, findet das snap-Binary zuerst und versucht es zu verwenden. GitHub Issue #4978 enthält eine vollständige Beschreibung.

Fehler 2: Headless-Standardwerte, die ein Display voraussetzen

OpenClaw wird mit headless: false und noSandbox: false als Browser-Standardwerte ausgeliefert. Das ergibt Sinn auf einem Mac oder Windows-Rechner mit Display. Auf einem VPS gibt es kein Display. Ohne explizite Konfiguration versucht Chromium, ein Fenster auf einem nicht vorhandenen Display-Server zu öffnen.

Zwei Konfigurationsänderungen beheben das Problem:

openclaw config set browser.headless true
openclaw config set browser.noSandbox true

Die meisten VPS-Anleitungen erwähnen das. Aber wenn Sie der Standard-OpenClaw-Installationsanleitung folgen, taucht keine der beiden Zeilen auf. Sie installieren, probieren den Browser, er schlägt fehl. Sie suchen den Fehler. Sie finden einen Blogbeitrag. Sie ändern die Konfiguration. Sie starten neu. Und dann kommt Fehler Nummer drei.

Fehler 3: Der unsichtbare OOM-Kill

Ein einzelner Chromium-Tab mit einigen geöffneten Seiten verbraucht 2 bis 4 GB RAM. Auf einem 4-GB-VPS bleibt so gut wie nichts für OpenClaw selbst, das Betriebssystem und andere laufende Dienste übrig.

Wenn Linux der Arbeitsspeicher ausgeht, beendet der OOM-Killer des Kernels den speicherhungrigsten Prozess. Das ist Chromium. Der Prozess stirbt. OpenClaw protokolliert ein Browser-Timeout. Kein Crash-Report, kein Stack-Trace, kein Hinweis darauf, dass Speicher das Problem war.

Es gibt auch eine subtilere Variante dieses Problems. Chromium startet für jeden Tab eigene Renderer-Prozesse. Wenn diese nicht ordnungsgemäß aufgeräumt werden, sammeln sie sich an. Ein GitHub Issue dokumentierte 39 verwaiste Renderer-Prozesse, die 3,8 GB RAM auf einem VPS verbrauchten, der eigentlich genug Reserven haben sollte.

Sie können das im Nachhinein mit dmesg | grep -i "oom\|killed\|chromium" prüfen, aber die meisten denken nicht daran, dort nachzusehen. Sie starten OpenClaw neu, es funktioniert ein paar Minuten, und dann passiert es wieder.

Die offizielle Seite zu Serveranforderungen empfiehlt mindestens 4 GB für ein Basis-Setup. Aber diese Zahl geht von keiner Browser-Automatisierung aus. Mit aktiviertem Browser sind 8 GB der realistische Mindestwert. Bei Hetzner ist das der Unterschied zwischen einem cpx22 (5 $/Monat) und einem cpx42 (17 $/Monat).

Fehler 4: Dockers fehlender Shared Memory

Wenn Sie OpenClaw in Docker betreiben (bei VPS-Deployments üblich), gibt es eine weitere Falle. Dockers Standard-/dev/shm beträgt 64 MB. Chromium nutzt Shared Memory für die Interprozesskommunikation. Wenn dieser aufgebraucht ist, stürzen Tabs lautlos ab oder rendern leere Seiten.

Die Lösung ist eine Zeile in Ihrer docker-compose.yml:

shm_size: '2gb'

Oder explizites Mounten:

volumes:
  - /dev/shm:/dev/shm

Das steht nicht in OpenClaws Setup-Anleitung. Es ist ein Docker-spezifisches Verhalten, das jede Anwendung mit Chromium betrifft. Wenn Sie aber noch nie Headless-Browser in Docker deployed haben, wissen Sie nicht, wonach Sie suchen müssen.

Fehler 5: Port-Kollisionen, vor denen niemand warnt

OpenClaws Browser Control Service läuft auf einem separaten Port vom Gateway. Standardmäßig ist es der Gateway-Port plus 2. Wenn Ihr Gateway auf 18789 läuft, sollte der Browser Control Service auf 18791 sein und der Extension Relay auf 18792.

In Docker ist der Browser Control Service unerreichbar, wenn Sie nur Port 18789 freigeben. Schlimmer noch: Das Gateway loggt „Browser control service ready”, auch wenn Port 18791 nie tatsächlich gebunden wird. Issue #17584 verfolgte dies bis zum Gateway zurück, das das falsche Modul importierte: eines, das die „ready”-Nachricht loggt, ohne den HTTP-Server zu starten. Das Log sagt, alles sei in Ordnung. Der Port ist tot.

In Kubernetes: Wenn ein anderer Container im selben Pod bereits Port 9222 (den Standard-CDP-Port) belegt, erkennt OpenClaws ensurePortAvailable()-Funktion den Port als belegt und verweigert die Verbindung, selbst wenn der Beleger genau die Chromium-Instanz ist, mit der OpenClaw kommunizieren sollte.

GitHub Issue #10994 dokumentiert einen Fall, in dem das VPS-Setup des Nutzers korrekt funktionierte. Nach einigen automatisierten Aktionen blieb der CDP-Port dann hängen. Die einzige Lösung war das Finden und Beenden verwaister Chromium-Prozesse, die den Port blockierten.

Warum sich diese Fehler potenzieren

Jedes dieser fünf Probleme hat eine bekannte Lösung. Aber sie interagieren miteinander. Sie lösen das snap-Problem und stoßen auf den Headless-Standard. Sie korrigieren die Konfiguration und Chromium startet. Es läuft zehn Minuten, dann schlägt der OOM-Killer zu. Sie fügen Swap-Space hinzu, und nun verursacht Dockers Shared-Memory-Limit lautlose Rendering-Fehler. Sie beheben das und entdecken, dass Port 18791 nicht freigegeben ist.

Die Debugging-Schleife sieht so aus: Fehler suchen, teilweise Lösung finden, Lösung anwenden, nächsten Fehler treffen, wiederholen. Ein Discord-Nutzer beschrieb, sein gesamtes OS „zum 3. oder 4. Mal” neu installiert zu haben. Ein anderer berichtete, der Browser sei „instabil”, obwohl er dachte, das Setup sei komplett. Ein dritter eröffnete ein Issue mit dem schlichten Titel „Browser tool consistently fails on VPS.”

Das Problem ist nicht, dass eine einzelne Lösung schwierig wäre. Das Problem ist, dass es fünf davon gibt, sie von Ihrem spezifischen OS, Paketmanager, Container-Runtime und VPS-Anbieter abhängen, und ein einziger Fehler in der Kette bedeutet, dass der Browser nicht funktioniert.

Dem OpenClaw-Team ist zugutezuhalten, dass es stetig verwandte Bugs behebt. Das irreführende „ready”-Log, die Bereinigung verwaister Renderer und die CDP-Port-Behandlung haben sich in neueren Versionen alle verbessert. Aber die Upstream-Fixes beheben Symptome innerhalb von OpenClaws Code. Sie können nicht das richtige Chromium-Binary auf Ihrem Server installieren, Ihren Docker Shared Memory konfigurieren oder genug RAM für Browser-Automatisierung bereitstellen. Das bleibt Ihre Aufgabe.

Wie wir Chromium drei Mal zum Absturz brachten (und was wir daraus lernten)

Wir betreiben jeden OpenClaw.rocks Agent auf Kubernetes mit unserem Open-Source-Operator. Der Browser-Sidecar hat uns Wochen gekostet, bis er richtig funktionierte. Wir hatten unsere eigene Version jedes oben beschriebenen Problems, plus einige, die nur im Container-Orchestrierungs-Kontext auftreten.

Die Idee war einfach: Chromium als separaten Container neben OpenClaw betreiben, verbunden über CDP. Eine Zeile in der Custom Resource und der Browser funktioniert einfach.

spec:
  chromium:
    enabled: true

So kam diese eine Zeile tatsächlich zustande.

Absturz 1: Falscher Benutzer, schreibgeschütztes Dateisystem

Unser erster Versuch führte den Chromium-Container als UID 1001 mit einem schreibgeschützten Root-Dateisystem aus. Sicherheitsbewährte Praxis. Und komplett kaputt. Das browserless-Image erwartet UID 999 (blessuser), und Node.js ruft beim Start os.userInfo() auf, was mit ENOENT fehlschlägt, wenn die UID keinen /etc/passwd-Eintrag hat. Auch nach dem Korrigieren der UID blockierte das schreibgeschützte Dateisystem Chrome am Schreiben von Temp-Dateien. Der Sidecar stürzte bei jedem Start ab, bevor eine einzige Log-Zeile geschrieben wurde. Issue #12 enthält die vollständige Geschichte.

Absturz 2: Die WebSocket-Sicherheitsmauer

Mit dem endlich laufenden Container war Chromium aktiv, CDP antwortete auf Port 9222, aber OpenClaw weigerte sich, es zu nutzen. Das Gateway band sich an die Pod-LAN-IP (erforderlich für Kubernetes Service Routing), und OpenClaws Sicherheitsschicht blockierte Klartext-ws://-Verbindungen zu Nicht-Loopback-Adressen: „SECURITY ERROR: Gateway URL uses plaintext ws:// to a non-loopback address. Both credentials and chat data would be exposed to network interception.”

Eine berechtigte Sicherheitsprüfung. Aber in einem Kubernetes-Pod teilen sich alle Container einen Netzwerk-Namespace. Traffic zwischen ihnen verlässt nie den Node. Wir konnten OpenClaws Sicherheitsprüfung nicht ändern, also fügten wir einen nginx Reverse-Proxy-Sidecar hinzu, der auf allen Interfaces lauscht und an das Gateway auf Loopback weiterleitet. Das Gateway bleibt sicher. Der Service bleibt erreichbar. Issue #135 dokumentiert das Debugging.

Absturz 3: Port-3000-Kollision

Chromium lief. Das Gateway war geproxied. Aber der Browser stellte trotzdem keine Verbindung her. Das browserless-Image verwendet standardmäßig Port 3000, der mit OpenClaws internem Browser Control Service kollidierte. Und als wir auf Port 9222 wechselten, erkannte OpenClaws ensurePortAvailable() ihn als „von etwas anderem belegt” und verweigerte die Verbindung, weil in einem geteilten Netzwerk-Namespace der Port des Sidecars lokal aussieht.

Die Lösung war die Verwendung der Pod-IP-Adresse (über die Kubernetes Downward API) anstelle von localhost für die CDP-URL. Eine Nicht-Loopback-Adresse weist OpenClaw an, den Remote/Attach-Only-Modus zu verwenden: sich mit dem bereits Laufenden verbinden, anstatt einen eigenen Browser zu starten. PR #183 löste dieses Problem.

Das Ergebnis: fünf Fixes, automatisch angewendet

Jeder dieser Abstürze hat uns etwas gelehrt. Der aktuelle Operator kodiert all dieses Wissen:

Sidecar-Isolation. Chromium läuft in einem eigenen Container. Kein snap. Kein Playwright. Keine Headless-Flags. Das browserless-Image kümmert sich um all das.

Dedizierte Ressourcen. Der Sidecar bekommt eigene CPU- und Speicherlimits (250m-1000m CPU, 512Mi-2Gi RAM standardmäßig, konfigurierbar). Wenn Chromium sein Speicherlimit überschreitet, startet Kubernetes nur den Browser-Container neu. Ihr Agent läuft weiter.

Shared Memory. Der Operator mountet automatisch ein 1 GB großes speichergestütztes Volume unter /dev/shm. Keine Docker-shm_size-Konfiguration nötig.

Port-Routing. Pod-IP für die CDP-URL aktiviert den Remote-Modus. OpenClaw verbindet sich mit dem Sidecar, anstatt den Port selbst zu beanspruchen. Der ensurePortAvailable()-Konflikt verschwindet.

Eingebauter Anti-Bot-Schutz. Viele Websites erkennen Standard-Headless-Chromium und blockieren Automatisierung. Der Operator unterstützt extraArgs für den Chromium-Sidecar. So können Sie Flags wie --disable-blink-features=AutomationControlled und benutzerdefinierte User-Agents übergeben, ohne ein eigenes Container-Image zu bauen:

spec:
  chromium:
    enabled: true
    extraArgs:
      - "--disable-blink-features=AutomationControlled"
      - "--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
      - "--window-size=1920,1080"

Sicherheit ohne Kompromisse. Alle Linux-Capabilities entfernt, Privilege Escalation deaktiviert, seccomp RuntimeDefault, Non-Root UID 999. Kein --no-sandbox als Root.

Was das für Sie bedeutet

Wenn Sie OpenClaw auf einem VPS betreiben und der Browser funktioniert: Glückwunsch. Sie haben fünf verschiedene Fehlermodi bewältigt und es auf die andere Seite geschafft. Behalten Sie Ihr Setup. Sichern Sie Ihre Konfiguration.

Wenn der Browser nicht funktioniert, oder nur sporadisch, oder wenn Sie es leid sind, Chromium auf einem 5-Dollar-VPS zu debuggen, überlegen Sie, was Ihre Zeit wert ist.

OpenClaw.rocks betreibt jeden Agent auf Kubernetes mit dem oben beschriebenen Operator. Der Browser-Sidecar ist vorkonfiguriert. Speicher ist zugewiesen. Ports sind geroutet. Sicherheit ist gehärtet. Sie installieren nichts, konfigurieren nichts und debuggen nichts.

Ihr Agent bekommt einen Browser, der funktioniert. Jedes Mal. Direkt einsatzbereit.

Die fünf Fixes im Überblick

Wenn Sie beim Self-Hosting bleiben möchten, hier die vollständige Checkliste:

  1. Snap Chromium ersetzen durch Google Chrome .deb oder Playwrights eigenständiges Binary
  2. Headless-Modus aktivieren: openclaw config set browser.headless true und browser.noSandbox true
  3. 8 GB+ RAM bereitstellen oder 4 GB Swap für Browser-Automatisierung hinzufügen
  4. Shared Memory mounten in Docker: shm_size: '2gb'
  5. Alle drei Ports freigeben: Gateway, Browser Control (Gateway + 2) und Extension Relay (Gateway + 3)

Oder überspringen Sie die Checkliste. Holen Sie sich Ihren Assistenten auf OpenClaw.rocks und lassen Sie uns die Infrastruktur übernehmen.