Browserul OpenClaw pe VPS: de ce nu funcționează
„Am probleme uriașe cu VPS-ul meu. Reinstalez OpenClaw pentru a 3-a sau a 4-a oară.”
Acest mesaj a apărut pe Discord-ul OpenClaw luna trecută. Utilizatorul nu era singurul. Parcurgeți canalele comunității și veți găsi zeci de variații pe aceeași temă: instrumentul de browser eșuează, agentul nu poate ajunge la Chromium, VPS-ul rămâne fără memorie, ieri totul funcționa și azi nu mai merge.
Dacă citiți asta pentru că tocmai ați căutat „OpenClaw browser nu funcționează VPS”, sunteți în locul potrivit. Acest articol explică cele cinci lucruri care nu merg, de ce interacționează în moduri frustrante, și cum le-am rezolvat pe toate în operatorul Kubernetes OpenClaw.rocks ca să nu mai trebuiască niciodată să vă gândiți la configurarea browserului.
Eroarea pe care o vede toată lumea
Cel mai frecvent mesaj de eroare din comunitatea OpenClaw este acesta:
Can't reach the OpenClaw browser control service
(timed out after 15000ms)
Apare pe Ubuntu, Debian, în Docker, pe Hetzner, Hostinger, GCP și oriunde altundeva unde se încearcă rularea OpenClaw cu automatizare de browser. Logurile gateway-ului spun „Browser control service ready.” Dar când agentul încearcă să folosească browserul, expiră timpul de așteptare.
Eroarea este generică. Cauzele nu sunt. Există cel puțin cinci moduri distincte de eșec, iar din exterior arată toate identic.
Eșec 1: Snap Chromium și zidul AppArmor
Pe un server Ubuntu 22.04+ proaspăt instalat, which chromium-browser returnează /usr/bin/chromium-browser. Pare corect. Nu este.
Din Ubuntu 22.04, pachetul implicit Chromium este un snap. Când gateway-ul OpenClaw încearcă să lanseze acel binar printr-un serviciu systemd, stratul de confinare AppArmor îl blochează. Pachetul snap nu poate deschide porturile de depanare Chrome DevTools Protocol (CDP) prin sandbox. Binarul pornește, pare să funcționeze, apoi eșuează silențios la deschiderea portului de care OpenClaw are nevoie.
Veți vedea „Failed to start Chrome CDP on port 18800” în loguri, sau uneori nimic. Procesul browserului pornește și moare înainte de a scrie o singură linie de log.
Soluția este instalarea pachetului .deb Google Chrome sau folosirea binarului Chromium standalone de la Playwright din ~/.cache/ms-playwright/. Ambele ocolesc sandbox-ul snap. Dar soluția nu este evidentă. Detectarea browserului de către OpenClaw scanează căile standard în ordine, găsește mai întâi binarul snap și încearcă să-l folosească. Issue-ul GitHub #4978 conține o descriere completă.
Eșec 2: Setări headless care presupun un display
OpenClaw vine cu headless: false și noSandbox: false ca setări implicite ale browserului. Asta are sens pe un Mac sau PC Windows cu ecran. Pe un VPS nu există ecran. Fără configurare explicită, Chromium încearcă să deschidă o fereastră pe un server de afișare care nu există.
Două modificări de configurare rezolvă problema:
openclaw config set browser.headless true
openclaw config set browser.noSandbox true
Majoritatea ghidurilor VPS menționează asta. Dar dacă urmați instrucțiunile standard de instalare OpenClaw, niciuna dintre linii nu apare. Instalați, testați browserul, eșuează. Căutați eroarea. Găsiți o postare de blog. Modificați configurarea. Reporniți. Apoi treceți la eșecul numărul trei.
Eșec 3: OOM kill-ul invizibil
O singură filă Chromium cu câteva pagini deschise consumă 2 până la 4 GB de RAM. Pe un VPS de 4 GB, nu rămâne aproape nimic pentru OpenClaw însuși, sistemul de operare și orice alte servicii în execuție.
Când Linux rămâne fără memorie, OOM killer-ul kernelului termină procesul cel mai consumator de memorie. Acela este Chromium. Procesul moare. OpenClaw înregistrează un timeout al browserului. Fără raport de eroare, fără stack trace, fără indicație că memoria a fost problema.
Există și o versiune mai subtilă a acestei probleme. Chromium lansează procese renderer copil pentru fiecare filă. Dacă acestea nu sunt curățate corespunzător, se acumulează. Un issue GitHub a documentat 39 de procese renderer orfane consumând 3,8 GB de RAM pe un VPS care ar fi trebuit să aibă suficient spațiu.
Puteți verifica ulterior cu dmesg | grep -i "oom\|killed\|chromium", dar majoritatea oamenilor nu se gândesc să verifice acolo. Repornesc OpenClaw, funcționează câteva minute, apoi se întâmplă din nou.
Pagina oficială de cerințe server recomandă minimum 4 GB pentru o configurare de bază. Dar acel număr presupune absența automatizării de browser. Cu browserul activat, 8 GB este minimul realist. La Hetzner, aceasta este diferența dintre un cpx22 (5 $/lună) și un cpx42 (17 $/lună).
Eșec 4: Memoria partajată lipsă a Docker
Dacă rulați OpenClaw în Docker (obișnuit pentru implementări VPS), mai este o capcană. /dev/shm implicit al Docker este de 64 MB. Chromium folosește memoria partajată pentru comunicarea între procese. Când se epuizează, filele se blochează silențios sau randează pagini goale.
Soluția este o singură linie în docker-compose.yml:
shm_size: '2gb'
Sau montați explicit:
volumes:
- /dev/shm:/dev/shm
Aceasta nu este documentată în ghidul de configurare OpenClaw. Este un comportament specific Docker care afectează orice aplicație ce folosește Chromium, dar dacă nu ați implementat browsere headless în Docker înainte, nu ați ști să căutați asta.
Eșec 5: Coliziuni de porturi despre care nimeni nu a avertizat
Serviciul browser control al OpenClaw rulează pe un port separat de gateway. Implicit, este portul gateway plus 2. Dacă gateway-ul este pe 18789, serviciul browser control ar trebui să fie pe 18791, iar extension relay pe 18792.
În Docker, dacă expuneți doar portul 18789, serviciul browser control este inaccesibil din afara containerului. Mai rău, gateway-ul înregistrează „Browser control service ready” chiar și când portul 18791 nu se leagă niciodată. Issue #17584 a trasat problema până la gateway-ul care importa modulul greșit: unul care înregistrează mesajul „ready” fără a porni serverul HTTP. Logul spune că totul e bine. Portul este mort.
În Kubernetes, dacă un alt container din același pod folosește deja portul 9222 (portul CDP standard), funcția ensurePortAvailable() a OpenClaw detectează portul ca ocupat și refuză conexiunea, chiar dacă ocupantul este exact instanța Chromium cu care OpenClaw ar trebui să comunice.
Issue-ul GitHub #10994 documentează un caz în care configurarea VPS a utilizatorului funcționa corect. Apoi, după câteva acțiuni automatizate, portul CDP s-a blocat. Singura soluție a fost găsirea și terminarea proceselor Chromium rătăcite care blocau portul.
De ce aceste eșecuri se cumulează
Fiecare dintre cele cinci probleme are o soluție cunoscută. Dar interacționează. Rezolvați problema snap și dați de setarea implicită headless. Corectați configurarea și Chromium pornește. Rulează zece minute, apoi OOM killer-ul intervine. Adăugați spațiu swap, iar acum limita de memorie partajată a Docker provoacă erori silențioase de randare. Rezolvați asta și descoperiți că portul 18791 nu este expus.
Bucla de depanare arată astfel: căutați eroarea, găsiți o remediere parțială, aplicați remedierea, dați de următoarea eroare, repetați. Un utilizator Discord a descris reinstalarea întregului sistem de operare „pentru a 3-a sau a 4-a oară”. Altul a raportat că browserul era „instabil” după ceea ce credea că este o configurare completă. Un al treilea a deschis un issue intitulat simplu „Browser tool consistently fails on VPS”.
Problema nu este că fiecare remediere individuală este dificilă. Problema este că sunt cinci, depind de sistemul dumneavoastră de operare, managerul de pachete, runtime-ul de containere și furnizorul VPS specific, iar o singură eroare în lanț înseamnă că browserul nu funcționează.
Echipa OpenClaw merită recunoaștere pentru remedierea constantă a bug-urilor asociate. Logul „ready” înșelător, curățarea rendererelor orfane și gestionarea portului CDP s-au îmbunătățit în versiunile recente. Dar remedierile upstream tratează simptome din codul OpenClaw. Nu pot instala binarul Chromium corect pe serverul dumneavoastră, configura memoria partajată Docker sau aloca suficient RAM pentru automatizarea browserului. Acestea rămân responsabilitatea dumneavoastră.
Cum am spart Chromium de trei ori (și ce am învățat)
Rulăm fiecare agent OpenClaw.rocks pe Kubernetes cu operatorul nostru open source. Sidecar-ul browserului ne-a luat săptămâni să-l facem să funcționeze corect. Am întâlnit propria versiune a fiecărei probleme descrise mai sus, plus câteva care apar doar în contextul orchestrării de containere.
Ideea era simplă: rulați Chromium ca un container separat lângă OpenClaw, conectat prin CDP. O singură linie în Custom Resource și browserul pur și simplu funcționează.
spec:
chromium:
enabled: true
Iată cum a luat naștere această singură linie.
Crash 1: Utilizator greșit, sistem de fișiere read-only
Prima noastră încercare rula containerul Chromium ca UID 1001 cu un sistem de fișiere root read-only. Best practice de securitate. Și complet defect. Imaginea browserless așteaptă UID 999 (blessuser), iar Node.js apelează os.userInfo() la pornire, care eșuează cu ENOENT când UID-ul nu are intrare în /etc/passwd. Chiar și după corectarea UID-ului, sistemul de fișiere read-only împiedica Chrome să scrie fișiere temporare. Sidecar-ul se prăbușea la fiecare pornire înainte de a scrie o singură linie de log. Issue #12 conține povestea completă.
Crash 2: Zidul de securitate WebSocket
Cu containerul rulând în sfârșit, Chromium era activ, CDP răspundea pe portul 9222, dar OpenClaw refuza să-l folosească. Gateway-ul se lega de IP-ul LAN al pod-ului (necesar pentru routing-ul Kubernetes Service), iar stratul de securitate al OpenClaw bloca conexiunile ws:// în text clar către adrese non-loopback: „SECURITY ERROR: Gateway URL uses plaintext ws:// to a non-loopback address. Both credentials and chat data would be exposed to network interception.”
O verificare de securitate legitimă. Dar într-un pod Kubernetes, toate containerele partajează un namespace de rețea. Traficul între ele nu părăsește niciodată nodul. Nu puteam modifica verificarea de securitate a OpenClaw, așa că am adăugat un sidecar reverse proxy nginx care ascultă pe toate interfețele și redirecționează către gateway pe loopback. Gateway-ul rămâne securizat. Service-ul rămâne accesibil. Issue #135 documentează depanarea.
Crash 3: Coliziunea portului 3000
Chromium rula. Gateway-ul era proxied. Dar browserul tot nu se conecta. Imaginea browserless folosește portul 3000 implicit, care coliziona cu serviciul intern browser control al OpenClaw. Iar când am trecut pe portul 9222, funcția ensurePortAvailable() a OpenClaw l-a detectat ca „folosit de altceva” și a refuzat conexiunea, deoarece într-un namespace de rețea partajat, portul sidecar-ului arată local.
Soluția a fost folosirea adresei IP a pod-ului (prin Kubernetes Downward API) în loc de localhost pentru URL-ul CDP. O adresă non-loopback îi spune OpenClaw să folosească modul remote/attach-only: să se conecteze la ce rulează deja, în loc să încerce să lanseze propriul browser. PR #183 a rezolvat aceasta.
Rezultatul: cinci remedieri, aplicate automat
Fiecare dintre aceste crash-uri ne-a învățat ceva. Operatorul actual codifică toate acestea:
Izolarea sidecar. Chromium rulează în propriul container. Fără snap. Fără Playwright. Fără flag-uri headless. Imaginea browserless se ocupă de tot.
Resurse dedicate. Sidecar-ul primește propriile limite de CPU și memorie (250m-1000m CPU, 512Mi-2Gi RAM implicit, configurabil). Dacă Chromium depășește limita de memorie, Kubernetes repornește doar containerul browserului. Agentul dumneavoastră continuă să ruleze.
Memorie partajată. Operatorul montează automat un volum de 1 GB în memorie la /dev/shm. Fără configurare Docker shm_size necesară.
Rutarea porturilor. IP-ul pod-ului pentru URL-ul CDP activează modul remote. OpenClaw se conectează la sidecar în loc să încerce să revendice portul. Conflictul ensurePortAvailable() dispare.
Detecție anti-bot integrată. Multe site-uri web detectează Chromium headless implicit și blochează automatizarea. Operatorul suportă extraArgs pe sidecar-ul Chromium, astfel încât puteți transmite flag-uri precum --disable-blink-features=AutomationControlled și user agents personalizați fără a construi o imagine de container personalizată:
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"
Securitate fără compromisuri. Toate capabilitățile Linux eliminate, escaladarea privilegiilor dezactivată, seccomp RuntimeDefault, UID 999 non-root. Fără --no-sandbox ca root.
Ce înseamnă asta pentru dumneavoastră
Dacă rulați OpenClaw pe un VPS și browserul funcționează, felicitări. Ați navigat prin cinci moduri distincte de eșec și ați ieșit pe cealaltă parte. Păstrați configurarea. Faceți backup.
Dacă browserul nu funcționează, sau funcționează intermitent, sau v-ați săturat să depanați Chromium pe un VPS de 5 dolari, gândiți-vă cât valorează timpul dumneavoastră.
OpenClaw.rocks rulează fiecare agent pe Kubernetes cu operatorul descris mai sus. Sidecar-ul browserului este preconfigurat. Memoria este alocată. Porturile sunt rutate. Securitatea este întărită. Nu instalați nimic, nu configurați nimic și nu depanați nimic.
Agentul dumneavoastră primește un browser care funcționează. De fiecare dată. Gata de utilizare.
Cele cinci remedieri pe scurt
Dacă doriți să rămâneți la self-hosting, iată lista completă de verificare:
- Înlocuiți snap Chromium cu
.deb-ul Google Chrome sau binarul standalone Playwright - Activați modul headless:
openclaw config set browser.headless trueșibrowser.noSandbox true - Alocați 8 GB+ RAM sau adăugați 4 GB swap pentru automatizarea browserului
- Montați memoria partajată în Docker:
shm_size: '2gb' - Expuneți toate trei porturile: gateway, browser control (gateway + 2) și extension relay (gateway + 3)
Sau săriți peste listă. Obțineți asistentul pe OpenClaw.rocks și lăsați infrastructura în grija noastră.