„Имам огромни проблеми с моя VPS. Преинсталирам OpenClaw за 3-ти или 4-ти път.”

Това съобщение се появи в OpenClaw Discord миналия месец. Потребителят не беше единственият. Превъртете каналите на общността и ще намерите десетки вариации на същата тема: инструментът за браузър се проваля, агентът не може да достигне Chromium, VPS-ът свършва паметта, вчера всичко работеше, а днес не.

Ако четете това, защото току-що потърсихте „OpenClaw браузър не работи VPS”, вие сте на правилното място. Тази публикация обяснява петте неща, които се развалят, защо взаимодействат по разочароващи начини и как ги решихме всичките в Kubernetes оператора на OpenClaw.rocks, за да не се налага никога повече да се занимавате с настройка на браузър.

Грешката, която всички виждат

Най-честото съобщение за грешка в общността на OpenClaw е:

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

Появява се на Ubuntu, Debian, в Docker, на Hetzner, Hostinger, GCP и навсякъде другаде, където се опитват да стартират OpenClaw с автоматизация на браузъра. Логовете на gateway казват „Browser control service ready.” Но когато агентът опита да използва браузъра, идва timeout.

Грешката е обща. Причините не са. Има поне пет различни режима на отказ и отвън изглеждат идентични.

Отказ 1: Snap Chromium и стената на AppArmor

На прясно инсталиран Ubuntu 22.04+ сървър which chromium-browser връща /usr/bin/chromium-browser. Изглежда правилно. Не е.

От Ubuntu 22.04 насам, пакетът Chromium по подразбиране е snap. Когато gateway на OpenClaw опита да стартира този файл чрез systemd услуга, ограничителният слой на AppArmor го блокира. Snap пакетът не може да отвори портовете за дебъгване на Chrome DevTools Protocol (CDP) през пясъчника. Файлът се стартира, изглежда работи, а после тихо се проваля при отваряне на порта, от който OpenClaw се нуждае.

В логовете ще видите „Failed to start Chrome CDP on port 18800” или понякога нищо. Процесът на браузъра стартира и умира, преди да напише дори един ред в лога.

Решението е да инсталирате .deb пакета на Google Chrome или да използвате самостоятелния Chromium от Playwright от ~/.cache/ms-playwright/. И двата заобикалят snap пясъчника. Но решението не е очевидно. Детекцията на браузър в OpenClaw сканира стандартните пътища по ред, намира snap файла първи и опитва да го използва. GitHub issue #4978 съдържа пълно описание.

Отказ 2: Headless настройки по подразбиране, които предполагат дисплей

OpenClaw се доставя с headless: false и noSandbox: false като настройки по подразбиране. Това е логично на Mac или Windows с дисплей. На VPS няма дисплей. Без изрична конфигурация Chromium опитва да отвори прозорец на сървър за показване, който не съществува.

Две промени в конфигурацията решават проблема:

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

Повечето VPS ръководства споменават това. Но ако следвате стандартните инструкции за инсталация на OpenClaw, нито един от тези редове не се появява. Инсталирате, пробвате браузъра, проваля се. Търсите грешката. Намирате публикация в блог. Променяте конфигурацията. Рестартирате. И идва отказ номер три.

Отказ 3: Невидимият OOM kill

Един таб на Chromium с няколко отворени страници консумира 2 до 4 GB RAM. На VPS с 4 GB не остава почти нищо за самия OpenClaw, операционната система и другите работещи услуги.

Когато на Linux му свърши паметта, OOM killer на ядрото прекратява процеса, който консумира най-много памет. Това е Chromium. Процесът умира. OpenClaw записва timeout на браузъра. Няма доклад за срив, няма stack trace, няма индикация, че паметта е била проблемът.

Има и по-фина версия на този проблем. Chromium стартира дъщерни renderer процеси за всеки таб. Ако не бъдат почистени правилно, те се натрупват. Един GitHub issue документира 39 осиротели renderer процеса, консумиращи 3,8 GB RAM на VPS, който трябваше да има достатъчно резерв.

Можете да проверите след това с dmesg | grep -i "oom\|killed\|chromium", но повечето хора не се сещат да погледнат там. Рестартират OpenClaw, работи няколко минути, а после се случва отново.

Официалната страница за сървърни изисквания препоръчва минимум 4 GB за основна конфигурация. Но това число предполага липса на автоматизация на браузъра. С включен браузър 8 GB е реалистичният минимум. При Hetzner това е разликата между cpx22 (5 $/мес.) и cpx42 (17 $/мес.).

Отказ 4: Липсващата споделена памет на Docker

Ако стартирате OpenClaw в Docker (често срещано при VPS инсталации), има още един капан. Стандартният /dev/shm на Docker е 64 MB. Chromium използва споделена памет за междупроцесна комуникация. Когато свърши, табовете се сриват тихо или показват празни страници.

Решението е един ред в docker-compose.yml:

shm_size: '2gb'

Или монтирайте изрично:

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

Това не е документирано в ръководството за настройка на OpenClaw. Това е поведение, специфично за Docker, което засяга всяко приложение, използващо Chromium, но ако не сте разгръщали headless браузъри в Docker преди, не бихте знаели да търсите това.

Отказ 5: Сблъсъци на портове, за които никой не предупреди

Browser control услугата на OpenClaw работи на отделен порт от gateway. По подразбиране е портът на gateway плюс 2. Ако gateway е на 18789, browser control услугата трябва да е на 18791, а extension relay на 18792.

В Docker, ако изложите само порт 18789, browser control услугата е недостъпна отвън контейнера. Още по-лошо, gateway записва „Browser control service ready”, дори когато порт 18791 никога реално не се свързва. Issue #17584 проследи проблема до gateway, който импортираше грешния модул: такъв, който записва съобщението „ready”, без да стартира HTTP сървъра. Логът казва, че всичко е наред. Портът е мъртъв.

В Kubernetes, ако друг контейнер в същия pod вече използва порт 9222 (стандартният CDP порт), функцията ensurePortAvailable() на OpenClaw открива порта като зает и отказва свързване, дори ако заемащият е точно инстанцията на Chromium, с която OpenClaw трябва да комуникира.

GitHub issue #10994 документира случай, при който VPS конфигурацията на потребителя работеше правилно. След няколко автоматизирани действия CDP портът заседна. Единственото решение беше намирането и убиването на блуждаещи Chromium процеси, които държаха порта.

Защо тези откази се натрупват

Всеки от петте проблема има известно решение. Но те взаимодействат. Решавате проблема със snap и се удряте в headless настройката по подразбиране. Поправяте конфигурацията и Chromium стартира. Работи десет минути, после OOM killer удря. Добавяте swap пространство, а сега лимитът на споделена памет на Docker причинява тихи грешки при визуализация. Поправяте това и откривате, че порт 18791 не е изложен.

Цикълът на дебъгване изглежда така: търсене на грешка, намиране на частично решение, прилагане на решение, удряне в следваща грешка, повтаряне. Един Discord потребител описа преинсталиране на цялата операционна система „за 3-ти или 4-ти път”. Друг съобщи, че браузърът е „нестабилен” след това, което смяташе за пълна конфигурация. Трети отвори issue озаглавено просто „Browser tool consistently fails on VPS”.

Проблемът не е, че всяко отделно решение е трудно. Проблемът е, че са пет, зависят от вашата конкретна операционна система, пакетен мениджър, контейнер рънтайм и VPS доставчик, и една единствена грешка във веригата означава, че браузърът не работи.

Екипът на OpenClaw заслужава признание за постоянното поправяне на свързани бъгове. Подвеждащият „ready” лог, почистването на осиротели renderери и обработката на CDP порта са се подобрили в последните версии. Но upstream поправките адресират симптоми в кода на OpenClaw. Те не могат да инсталират правилния Chromium на вашия сървър, да конфигурират споделената памет на Docker или да разпределят достатъчно RAM за автоматизация на браузъра. Това остава ваша отговорност.

Как счупихме Chromium три пъти (и какво научихме)

Стартираме всеки OpenClaw.rocks агент на Kubernetes с нашия оператор с отворен код. Browser sidecar-ът ни отне седмици, докато заработи правилно. Срещнахме собствена версия на всеки описан проблем, плюс няколко, които се появяват само в контекст на оркестрация на контейнери.

Идеята беше проста: стартирайте Chromium като отделен контейнер до OpenClaw, свързан чрез CDP. Един ред в Custom Resource и браузърът просто работи.

spec:
  chromium:
    enabled: true

Ето как този един ред реално се появи.

Срив 1: Грешен потребител, файлова система само за четене

Първият ни опит стартира Chromium контейнера като UID 1001 с файлова система root само за четене. Най-добра практика за сигурност. И напълно счупено. Browserless образът очаква UID 999 (blessuser), а Node.js извиква os.userInfo() при стартиране, което се проваля с ENOENT, когато UID-ът няма запис в /etc/passwd. Дори след коригиране на UID-а, файловата система само за четене блокираше Chrome да записва временни файлове. Sidecar-ът се сриваше при всяко стартиране, преди да запише дори един ред в лога. Issue #12 съдържа пълната история.

Срив 2: WebSocket стената за сигурност

С контейнера най-накрая работещ, Chromium беше активен, CDP отговаряше на порт 9222, но OpenClaw отказваше да го използва. Gateway се свързваше към LAN IP на pod-а (необходимо за маршрутизация на Kubernetes Service), а слоят за сигурност на OpenClaw блокираше нешифровани ws:// връзки към не-loopback адреси: „SECURITY ERROR: Gateway URL uses plaintext ws:// to a non-loopback address. Both credentials and chat data would be exposed to network interception.”

Легитимна проверка за сигурност. Но в Kubernetes pod всички контейнери споделят мрежов namespace. Трафикът между тях никога не напуска нода. Не можехме да променим проверката за сигурност на OpenClaw, затова добавихме nginx reverse proxy sidecar, който слуша на всички интерфейси и препраща към gateway на loopback. Gateway остава защитен. Service остава достъпен. Issue #135 документира дебъгването.

Срив 3: Колизия на порт 3000

Chromium работеше. Gateway имаше proxy. Но браузърът все още не се свързваше. Browserless образът използва порт 3000 по подразбиране, който се сблъскваше с вътрешната browser control услуга на OpenClaw. А когато преминахме на порт 9222, ensurePortAvailable() на OpenClaw го откри като „използван от нещо друго” и отказа свързване, защото в споделен мрежов namespace портът на sidecar-а изглежда локален.

Решението беше използването на IP адреса на pod-а (чрез Kubernetes Downward API) вместо localhost за CDP URL. Не-loopback адрес казва на OpenClaw да използва remote/attach-only режим: свържете се с това, което вече работи, вместо да опитвате да стартирате собствен браузър. PR #183 реши това.

Резултатът: пет поправки, приложени автоматично

Всеки от тези сривове ни научи на нещо. Текущият оператор кодира всичко:

Sidecar изолация. Chromium работи в собствен контейнер. Без snap. Без Playwright. Без headless флагове. Browserless образът се грижи за всичко.

Отделени ресурси. Sidecar получава собствени CPU и лимити на паметта (250m-1000m CPU, 512Mi-2Gi RAM по подразбиране, конфигурируемо). Ако Chromium надвиши лимита си на памет, Kubernetes рестартира само контейнера на браузъра. Вашият агент продължава да работи.

Споделена памет. Операторът автоматично монтира 1 GB том, базиран на паметта, на /dev/shm. Не е необходима Docker shm_size конфигурация.

Маршрутизация на портове. Pod IP за CDP URL активира отдалечен режим. OpenClaw се свързва към sidecar-а вместо да опитва да заеме порта. Конфликтът ensurePortAvailable() изчезва.

Вградена анти-бот детекция. Много уебсайтове разпознават стандартния headless Chromium и блокират автоматизация. Операторът поддържа extraArgs на Chromium sidecar-а, така че можете да подавате флагове като --disable-blink-features=AutomationControlled и потребителски user agents без да строите потребителски образ на контейнер:

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"

Сигурност без компромиси. Всички Linux capabilities премахнати, ескалация на привилегии деактивирана, seccomp RuntimeDefault, non-root UID 999. Без --no-sandbox като root.

Какво означава това за вас

Ако стартирате OpenClaw на VPS и браузърът работи, поздравления. Преминахте през пет различни режима на отказ и излязохте от другата страна. Запазете конфигурацията си. Направете резервно копие.

Ако браузърът не работи, или работи периодично, или сте уморени от дебъгване на Chromium на VPS за 5 долара, помислете колко струва времето ви.

OpenClaw.rocks стартира всеки агент на Kubernetes с оператора, описан по-горе. Browser sidecar-ът е предварително конфигуриран. Паметта е разпределена. Портовете са маршрутизирани. Сигурността е подсилена. Не инсталирате нищо, не конфигурирате нищо и не дебъгвате нищо.

Вашият агент получава браузър, който работи. Всеки път. Направо от кутията.

Петте поправки накратко

Ако искате да останете на self-hosting, ето пълния списък:

  1. Заменете snap Chromium с .deb пакета на Google Chrome или самостоятелния файл на Playwright
  2. Активирайте headless режим: openclaw config set browser.headless true и browser.noSandbox true
  3. Разпределете 8 GB+ RAM или добавете 4 GB swap за автоматизация на браузъра
  4. Монтирайте споделена памет в Docker: shm_size: '2gb'
  5. Изложете и трите порта: gateway, browser control (gateway + 2) и extension relay (gateway + 3)

Или пропуснете списъка. Вземете вашия асистент на OpenClaw.rocks и оставете инфраструктурата на нас.