„Mam ogromne problemy z moim VPS. Reinstaluje OpenClaw po raz 3. lub 4.”

Ta wiadomość pojawiła się na Discordzie OpenClaw w zeszłym miesiącu. Użytkownik nie był jedyny. Przewiń kanały społeczności, a znajdziesz dziesiątki wariantów tego samego tematu: narzędzie przeglądarki nie działa, agent nie może połączyć się z Chromium, VPS wyczerpał pamięć, wczoraj wszystko działało, a dzisiaj nie.

Jeśli czytasz to, bo właśnie wyszukałeś „OpenClaw przeglądarka nie działa VPS”, trafiłeś we właściwe miejsce. Ten artykuł wyjaśnia pięć rzeczy, które się psują, dlaczego współdziałają na frustrujące sposoby, oraz jak rozwiązaliśmy je wszystkie w operatorze Kubernetes OpenClaw.rocks, żebyś nigdy więcej nie musiał się zajmować konfiguracją przeglądarki.

Błąd, który wszyscy widzą

Najczęstszy komunikat o błędzie w społeczności OpenClaw to ten:

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

Pojawia się na Ubuntu, Debianie, w Dockerze, na Hetzner, Hostinger, GCP i wszędzie indziej, gdzie ludzie próbują uruchomić OpenClaw z automatyzacją przeglądarki. Logi gateway mówią „Browser control service ready.” Ale gdy agent próbuje użyć przeglądarki, następuje timeout.

Błąd jest generyczny. Przyczyny nie są. Jest co najmniej pięć odrębnych trybów awarii, a z zewnątrz wyglądają identycznie.

Awaria 1: Snap Chromium i mur AppArmor

Na świeżym serwerze Ubuntu 22.04+ polecenie which chromium-browser zwraca /usr/bin/chromium-browser. Wygląda poprawnie. Nie jest.

Od Ubuntu 22.04 domyślny pakiet Chromium to snap. Gdy gateway OpenClaw próbuje uruchomić ten plik binarny przez usługę systemd, warstwa ograniczeń AppArmor go blokuje. Pakiet snap nie może otworzyć portów debugowania Chrome DevTools Protocol (CDP) przez sandbox. Plik binarny uruchamia się, wydaje się działać, a potem cicho nie otwiera portu, którego OpenClaw potrzebuje.

W logach zobaczysz „Failed to start Chrome CDP on port 18800” lub czasem nic. Proces przeglądarki startuje i umiera, zanim napisze choćby jedną linię logu.

Rozwiązaniem jest instalacja pakietu .deb Google Chrome lub użycie samodzielnego pliku binarnego Chromium z Playwright z ~/.cache/ms-playwright/. Oba omijają sandbox snap. Ale rozwiązanie nie jest oczywiste. Detekcja przeglądarki w OpenClaw skanuje standardowe ścieżki po kolei, znajduje najpierw plik binarny snap i próbuje go użyć. Issue na GitHubie #4978 zawiera pełny opis.

Awaria 2: Domyślne ustawienia headless zakładające wyświetlacz

OpenClaw jest dostarczany z headless: false i noSandbox: false jako domyślnymi ustawieniami przeglądarki. Ma to sens na Macu lub komputerze z Windowsem i wyświetlaczem. Na VPS nie ma wyświetlacza. Bez jawnej konfiguracji Chromium próbuje otworzyć okno na serwerze wyświetlacza, który nie istnieje.

Dwie zmiany konfiguracji rozwiązują problem:

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

Większość przewodników VPS o tym wspomina. Ale jeśli podążasz za standardową instrukcją instalacji OpenClaw, żadna z tych linii się nie pojawia. Instalujesz, próbujesz przeglądarki, nie działa. Szukasz błędu. Znajdujesz artykuł. Zmieniasz konfigurację. Restartujesz. I przechodzisz do awarii numer trzy.

Awaria 3: Niewidzialny OOM kill

Pojedyncza karta Chromium z kilkoma otwartymi stronami zużywa od 2 do 4 GB RAM. Na VPS z 4 GB nie zostaje prawie nic dla samego OpenClaw, systemu operacyjnego i innych uruchomionych usług.

Kiedy Linux wyczerpie pamięć, OOM killer jądra kończy proces zużywający najwięcej pamięci. To Chromium. Proces umiera. OpenClaw loguje timeout przeglądarki. Żadnego raportu o awarii, żadnego stack trace, żadnej wskazówki, że problemem była pamięć.

Jest też subtelniejsza wersja tego problemu. Chromium uruchamia procesy renderujące dla każdej karty. Jeśli nie zostaną prawidłowo wyczyszczone, kumulują się. Pewien issue na GitHubie udokumentował 39 osieroconych procesów renderujących zużywających 3,8 GB RAM na VPS, który miał mieć spory zapas.

Możesz to sprawdzić po fakcie za pomocą dmesg | grep -i "oom\|killed\|chromium", ale większość ludzi nie myśli, żeby tam zajrzeć. Restartują OpenClaw, działa kilka minut, a potem zdarza się ponownie.

Oficjalna strona wymagań serwerowych rekomenduje minimum 4 GB dla podstawowej konfiguracji. Ale ta liczba zakłada brak automatyzacji przeglądarki. Z włączoną przeglądarką 8 GB to realistyczne minimum. Na Hetznerze to różnica między cpx22 (5 $/mies.) a cpx42 (17 $/mies.).

Awaria 4: Brakująca pamięć współdzielona Dockera

Jeśli uruchamiasz OpenClaw w Dockerze (typowe dla wdrożeń VPS), czeka kolejna pułapka. Domyślny /dev/shm Dockera to 64 MB. Chromium używa pamięci współdzielonej do komunikacji międzyprocesowej. Gdy się wyczerpie, karty cicho padają lub wyświetlają puste strony.

Rozwiązanie to jedna linia w docker-compose.yml:

shm_size: '2gb'

Lub zamontuj jawnie:

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

To nie jest udokumentowane w przewodniku instalacji OpenClaw. To zachowanie specyficzne dla Dockera, które dotyczy każdej aplikacji używającej Chromium, ale jeśli nigdy nie wdrażałeś przeglądarek headless w Dockerze, nie wiedziałbyś, że tego szukać.

Awaria 5: Kolizje portów, o których nikt nie ostrzega

Usługa kontroli przeglądarki OpenClaw działa na oddzielnym porcie od gateway. Domyślnie jest to port gateway plus 2. Jeśli Twój gateway jest na 18789, usługa kontroli przeglądarki powinna być na 18791, a relay rozszerzeń na 18792.

W Dockerze, jeśli udostępnisz tylko port 18789, usługa kontroli przeglądarki jest nieosiągalna spoza kontenera. Co gorsza, gateway loguje „Browser control service ready”, nawet gdy port 18791 nigdy się nie zbinduje. Issue #17584 wyśledził to do gateway importującego zły moduł: taki, który loguje wiadomość „ready” bez uruchamiania serwera HTTP. Log mówi, że wszystko jest w porządku. Port jest martwy.

W Kubernetesie, jeśli inny kontener w tym samym podzie już używa portu 9222 (standardowy port CDP), funkcja ensurePortAvailable() OpenClaw wykrywa port jako zajęty i odmawia połączenia, nawet jeśli zajmujący to dokładnie ta instancja Chromium, z którą OpenClaw powinien się komunikować.

Issue na GitHubie #10994 dokumentuje przypadek, gdzie konfiguracja VPS użytkownika działała poprawnie. Potem, po kilku zautomatyzowanych akcjach, port CDP się zablokował. Jedynym rozwiązaniem było znalezienie i zabicie zbłąkanych procesów Chromium trzymających port.

Dlaczego te awarie się kumulują

Każdy z tych pięciu problemów ma znane rozwiązanie. Ale one ze sobą współdziałają. Rozwiązujesz problem snap i trafiasz na domyślne ustawienie headless. Poprawiasz konfigurację i Chromium startuje. Działa dziesięć minut, potem OOM killer go ubija. Dodajesz przestrzeń swap, a teraz limit pamięci współdzielonej Dockera powoduje ciche błędy renderowania. Naprawiasz to i odkrywasz, że port 18791 nie jest udostępniony.

Pętla debugowania wygląda tak: szukać błędu, znaleźć częściową poprawkę, zastosować poprawkę, trafić na kolejny błąd, powtórzyć. Jeden użytkownik Discorda opisał reinstalację całego systemu operacyjnego „po raz 3. lub 4.” Inny zgłosił, że przeglądarka była „niestabilna” po tym, co uważał za kompletną konfigurację. Trzeci otworzył issue zatytułowany po prostu „Browser tool consistently fails on VPS.”

Problem nie polega na tym, że każda pojedyncza poprawka jest trudna. Problem polega na tym, że jest ich pięć, zależą od Twojego konkretnego systemu operacyjnego, menedżera pakietów, runtime kontenerów i dostawcy VPS, a jeden błąd w łańcuchu oznacza, że przeglądarka nie działa.

Trzeba przyznać zespołowi OpenClaw, że systematycznie naprawia powiązane błędy. Mylący log „ready”, czyszczenie osieroconych rendererów i obsługa portu CDP poprawiły się w ostatnich wersjach. Ale poprawki upstream adresują symptomy w kodzie OpenClaw. Nie mogą zainstalować właściwego pliku binarnego Chromium na Twoim serwerze, skonfigurować pamięci współdzielonej Dockera ani przydzielić wystarczającej ilości RAM na automatyzację przeglądarki. To pozostaje Twoja odpowiedzialność.

Jak zepsuliśmy Chromium trzy razy (i czego się nauczyliśmy)

Każdego agenta OpenClaw.rocks uruchamiamy na Kubernetesie z naszym operatorem open source. Sidecar przeglądarki zajął nam tygodnie, zanim zaczął działać prawidłowo. Natknęliśmy się na własną wersję każdego opisanego wyżej problemu, plus kilka, które pojawiają się tylko w kontekście orkiestracji kontenerów.

Pomysł był prosty: uruchomić Chromium jako osobny kontener obok OpenClaw, połączony przez CDP. Jedna linia w Custom Resource i przeglądarka po prostu działa.

spec:
  chromium:
    enabled: true

Oto jak ta jedna linia faktycznie powstała.

Crash 1: Zły użytkownik, system plików tylko do odczytu

Nasza pierwsza próba uruchamiała kontener Chromium jako UID 1001 z systemem plików root tylko do odczytu. Najlepsza praktyka bezpieczeństwa. I kompletnie zepsute. Obraz browserless oczekuje UID 999 (blessuser), a Node.js wywołuje przy starcie os.userInfo(), co kończy się błędem ENOENT, gdy UID nie ma wpisu w /etc/passwd. Nawet po poprawieniu UID system plików tylko do odczytu blokował Chrome przed zapisem plików tymczasowych. Sidecar padał przy każdym starcie, zanim napisał choćby jedną linię logu. Issue #12 zawiera pełną historię.

Crash 2: Mur bezpieczeństwa WebSocket

Z kontenerem wreszcie działającym, Chromium był aktywny, CDP odpowiadał na porcie 9222, ale OpenClaw odmawiał jego użycia. Gateway wiązał się z IP LAN poda (wymagane dla routingu Kubernetes Service), a warstwa bezpieczeństwa OpenClaw blokowała połączenia ws:// w postaci jawnej do adresów nie-loopback: „SECURITY ERROR: Gateway URL uses plaintext ws:// to a non-loopback address. Both credentials and chat data would be exposed to network interception.”

Uzasadniona kontrola bezpieczeństwa. Ale w podzie Kubernetes wszystkie kontenery współdzielą namespace sieciowy. Ruch między nimi nigdy nie opuszcza węzła. Nie mogliśmy zmienić kontroli bezpieczeństwa OpenClaw, więc dodaliśmy sidecar reverse proxy nginx, który nasłuchuje na wszystkich interfejsach i przekierowuje do gateway na loopback. Gateway pozostaje bezpieczny. Service pozostaje osiągalny. Issue #135 dokumentuje debugging.

Crash 3: Kolizja portu 3000

Chromium działał. Gateway miał proxy. Ale przeglądarka wciąż się nie łączyła. Obraz browserless domyślnie używa portu 3000, który kolidował z wewnętrzną usługą kontroli przeglądarki OpenClaw. A gdy przeszliśmy na port 9222, funkcja ensurePortAvailable() OpenClaw wykryła go jako „używany przez coś innego” i odmówiła połączenia, ponieważ we współdzielonym namespace sieciowym port sidecara wygląda jak lokalny.

Rozwiązaniem było użycie adresu IP poda (przez Kubernetes Downward API) zamiast localhost dla URL CDP. Adres nie-loopback mówi OpenClaw, żeby użył trybu remote/attach-only: połączył się z tym, co już działa, zamiast próbować uruchomić własną przeglądarkę. PR #183 rozwiązał to.

Rezultat: pięć poprawek, stosowanych automatycznie

Każdy z tych crashów nas czegoś nauczył. Obecny operator koduje całą tę wiedzę:

Izolacja sidecar. Chromium działa we własnym kontenerze. Żadnego snap. Żadnego Playwright. Żadnych flag headless. Obraz browserless zajmuje się tym wszystkim.

Dedykowane zasoby. Sidecar dostaje własne limity CPU i pamięci (250m-1000m CPU, 512Mi-2Gi RAM domyślnie, konfigurowalne). Jeśli Chromium przekroczy swój limit pamięci, Kubernetes restartuje tylko kontener przeglądarki. Twój agent działa dalej.

Pamięć współdzielona. Operator automatycznie montuje 1 GB wolumenu opartego na pamięci w /dev/shm. Żadnej konfiguracji Docker shm_size.

Routing portów. IP poda dla URL CDP aktywuje tryb zdalny. OpenClaw łączy się z sidecarem zamiast próbować zająć port. Konflikt ensurePortAvailable() znika.

Wbudowane wykrywanie anty-bot. Wiele stron wykrywa domyślne headless Chromium i blokuje automatyzację. Operator obsługuje extraArgs na sidecarze Chromium, dzięki czemu możesz przekazywać flagi jak --disable-blink-features=AutomationControlled i niestandardowe user agenty bez budowania własnego obrazu kontenera:

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"

Bezpieczeństwo bez kompromisów. Wszystkie capability Linuxa usunięte, eskalacja uprawnień wyłączona, seccomp RuntimeDefault, non-root UID 999. Żadnego --no-sandbox jako root.

Co to oznacza dla Ciebie

Jeśli uruchamiasz OpenClaw na VPS i przeglądarka działa, gratulacje. Przeszedłeś przez pięć odrębnych trybów awarii i wyszedłeś z tego cało. Zachowaj swoją konfigurację. Zrób backup.

Jeśli przeglądarka nie działa, lub działa sporadycznie, lub masz dość debugowania Chromium na VPS za 5 dolarów, zastanów się, ile wart jest Twój czas.

OpenClaw.rocks uruchamia każdego agenta na Kubernetesie z operatorem opisanym powyżej. Sidecar przeglądarki jest wstępnie skonfigurowany. Pamięć jest przydzielona. Porty są routowane. Bezpieczeństwo jest wzmocnione. Nic nie instalujesz, nic nie konfigurujesz i nic nie debugujesz.

Twój agent dostaje przeglądarkę, która działa. Za każdym razem. Od razu po uruchomieniu.

Pięć poprawek w skrócie

Jeśli chcesz pozostać przy self-hostingu, oto kompletna lista kontrolna:

  1. Zastąp snap Chromium pakietem .deb Google Chrome lub samodzielnym plikiem binarnym Playwright
  2. Włącz tryb headless: openclaw config set browser.headless true i browser.noSandbox true
  3. Przydziel 8 GB+ RAM lub dodaj 4 GB swap na automatyzację przeglądarki
  4. Zamontuj pamięć współdzieloną w Dockerze: shm_size: '2gb'
  5. Udostępnij wszystkie trzy porty: gateway, kontrola przeglądarki (gateway + 2) i relay rozszerzeń (gateway + 3)

Albo pomiń listę. Zdobądź swojego asystenta na OpenClaw.rocks i pozwól nam zająć się infrastrukturą.