Как запустить Chrome в докере и не сойти с ума от тормозов

18 мая 2026
1,032
82
3
3 недели

Знакомая история: нужно автоматизировать сбор данных или протестировать веб-приложение, и вы тянете в проект Playwright или Puppeteer. Всё идет хорошо, пока дело не доходит до деплоя. Тут начинаются танцы с бубном вокруг зависимостей Chromium, вечно «отваливающихся» сессий и дикого жора оперативной памяти. А если нужно еще и глазами посмотреть, что там творится внутри контейнера, то настройка VNC превращается в отдельный квест на вечер.

Недавно наткнулся на репозиторий kernel-images. Ребята из команды Kernel решили собрать всё, что нужно для нормальной работы браузерных агентов, в одном месте. По сути, это готовые образы Chrome, которые живут в песочнице и которыми можно рулить удаленно без боли.

Kernel Logo

Что внутри этого ящика

Проект предлагает не просто «еще один Dockerfile с хромом». Главная фишка здесь — связка Docker и Unikraft (это такая штука для создания микро-виртуалок или юникернелов). Если с докером всё плюс-минус понятно, то юникернелы дают несколько очень приятных бонусов для тех, кто делает AI-агентов или сложные парсеры.

Вот что умеет этот стек:

Реклама
  • Работает с Playwright и Puppeteer через стандартный протокол CDP (Chrome DevTools Protocol).
  • Стримит живую картинку из браузера прямо в интерфейс через WebRTC или noVNC. Можно не только смотреть, но и кликать мышкой.
  • Умеет записывать видео сессии.
  • Если использовать юникернел, браузер уходит в «спячку» при отсутствии активности и просыпается меньше чем за 20 миллисекунд.

Как это пощупать в Docker

Для большинства из нас Docker — самый понятный путь. Ребята подготовили скрипты для сборки и запуска chromium-headful. Это версия с графическим интерфейсом, которая крутится внутри контейнера.

Сборка выглядит стандартно:

cd images/chromium-headful
IMAGE=kernel-docker ./build-docker.sh
IMAGE=kernel-docker ENABLE_WEBRTC=true ./run-docker.sh

После запуска браузер слушает порт 9222. Это входная точка для ваших скриптов.

Подключение кода

Самое классное, что вам не нужно менять логику своих скриптов. Если у вас уже есть код на Playwright, вы просто указываете ему адрес запущенного контейнера.

Сначала получаем URL воркер-сокета (это стандартный шаг для CDP):

const response = await fetch("http://localhost:9222/json/version");
const { webSocketDebuggerUrl } = await response.json();

А потом скармливаем этот URL вашему любимому фреймворку:

// Для Playwright это выглядит так
const browser = await chromium.connectOverCDP(webSocketDebuggerUrl);

// А для Puppeteer так
const browser = await puppeteer.connect({
  browserWSEndpoint: webSocketDebuggerUrl,
});

Теперь ваш скрипт управляет браузером, который изолирован в контейнере, а вы можете открыть порт 443 в браузере и смотреть, как там бегает курсор и нажимаются кнопки.

Зачем тут юникернелы

Честно скажу, технология Unikraft может показаться избыточной, если вам нужно просто раз в день зайти на сайт и нажать кнопку. Но если вы строите инфраструктуру для сотен браузерных агентов, всё меняется.

Юникернел позволяет «заморозить» состояние браузера со всеми куками, открытыми вкладками и даже зумом страницы. Когда запросов нет, такая виртуалка почти не ест ресурсы. Как только прилетает сетевой пакет — она мгновенно восстанавливается из снимка (снапшота). В Docker такого добиться гораздо сложнее.

Запись экрана без костылей

Часто в автоматизации нужно сохранить доказательства работы или понять, почему упал тест. В kernel-images встроили простенькое API для записи.

Включаем флаг WITH_KERNEL_IMAGES_API=true при старте и дергаем обычный curl:

# Старт записи
curl http://localhost:10001/recording/start -d {}

# Тут работает ваш скрипт

# Стоп и скачивание mp4
curl http://localhost:10001/recording/stop -d {}
curl http://localhost:10001/recording/download --output result.mp4

Кому это пригодится

Проект точно стоит покрутить, если:

  1. Вы делаете AI-агентов, которым нужен визуальный фидбек от браузера.
  2. Вам надоело возиться с настройкой xvfb и VNC в докере.
  3. Вы хотите организовать ферму браузеров, которые не будут отъедать всю память сервера в простое.

Из минусов — документация пока короткая, и для запуска юникернела придется поставить kraft CLI и немного разобраться в их облаке (или разворачивать свое). Но даже как база для кастомных Docker-образов с Chrome, этот репозиторий — отличная находка.

Попробовать стоит хотя бы ради того, чтобы увидеть, насколько плавно может работать WebRTC-стриминг из контейнера по сравнению с тормозным VNC.

🍪 Мы используем файлы cookie и сервис аналитики Яндекс.Метрика, чтобы сайт работал лучше. Продолжая пользоваться devtrends.ru, вы соглашаетесь с обработкой данных согласно Политике конфиденциальности.