Гид по технологиям

Запуск Puppeteer в Docker: настройка, флаги и практические рекомендации

6 min read DevOps Обновлено 02 Dec 2025
Puppeteer в Docker: настройка и лучшие практики
Puppeteer в Docker: настройка и лучшие практики

Логотип Puppeteer на белом фоне

Быстрые ссылки

  • Основные требования
  • Использование Puppeteer в Docker
  • Дополнительные советы и чеклист
  • Заключение

Puppeteer — это библиотека для Node.js, которая даёт программный доступ к браузеру Chrome (а в новых релизах также часть поддержки Firefox). Она часто используется для автоматизированного тестирования, архивирования страниц и создания скриншотов. Puppeteer управляет браузером через понятный API: навигация по страницам, клики по элементам формы и выполнение команд браузера.

Запуск Puppeteer в Docker иногда вызывает сложности: headless-режим Chrome требует множества системных зависимостей. Ниже — детальная инструкция по установке зависимостей и настройке окружения, чтобы Puppeteer работал в Kubernetes, в локальном контейнере на машине разработчика или в CI-пайплайне.

Основные требования

В примерах используется образ на базе Debian. Если вы применяете другую базу, адаптируйте команды пакета менеджера. Официальный Node.js-образ — хорошая отправная точка: Node уже установлен, и вам не нужно вручную ставить его внутри контейнера.

Puppeteer распространяется через npm и по умолчанию включает в пакет последнюю собранную версию Chromium. Теоретически достаточно выполнить npm install puppeteer, но в чистом Docker-образе обычно отсутствуют системные библиотеки, необходимые для запуска Chromium.

Chrome — тяжёлая программа с GUI, и даже в headless-режиме она требует шрифтов, графических библиотек и конфигурации. Все эти зависимости нужно установить в Dockerfile.

Ниже — минимальный пример Dockerfile, адаптированный для Debian-подобного образа. Он показывает список пакетов, которые часто требуются для корректной работы Chromium, и шаги установки Puppeteer:

FROM node:latest

WORKDIR /puppeteer

# Установка системных зависимостей для запуска Chromium
RUN apt-get update && apt-get install -y \
    fonts-liberation \
    gconf-service \
    libappindicator1 \
    libasound2 \
    libatk1.0-0 \
    libcairo2 \
    libcups2 \
    libfontconfig1 \
    libgbm-dev \
    libgdk-pixbuf2.0-0 \
    libgtk-3-0 \
    libicu-dev \
    libjpeg-dev \
    libnspr4 \
    libnss3 \
    libpango-1.0-0 \
    libpangocairo-1.0-0 \
    libpng-dev \
    libx11-6 \
    libx11-xcb1 \
    libxcb1 \
    libxcomposite1 \
    libxcursor1 \
    libxdamage1 \
    libxext6 \
    libxfixes3 \
    libxi6 \
    libxrandr2 \
    libxrender1 \
    libxss1 \
    libxtst6 \
    xdg-utils \
  --no-install-recommends && rm -rf /var/lib/apt/lists/*

# Копируем package.json и package-lock.json и ставим зависимости строго
COPY package.json ./
COPY package-lock.json ./
RUN npm ci

# Делаем бандл Chromium исполняемым, чтобы избежать ошибок прав при запуске
RUN chmod -R o+rwx node_modules/puppeteer/.local-chromium

# Копируем код приложения
COPY . .

# Точка входа (пример). Замените на вашу команду запуска.
CMD ["node", "index.js"]

Объяснение ключевых шагов:

  • apt-get install: устанавливает библиотеки, которых обычно не хватает в минимальных контейнерах. Это шрифты, графические библиотеки, поддержка изображений и т.д.
  • npm ci: детерминированная установка зависимостей на основе package-lock.json. Лучше для CI.
  • chmod -R: даёт доступ к бинарнику Chromium, включённому в пакет puppeteer, чтобы избежать ошибок прав.

Иногда удобнее не скачивать Chromium в момент установки npm. Перед npm ci можно установить переменную окружения PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1. Тогда Puppeteer не будет скачивать Chromium, и вы сможете поставить свой системный бинарник браузера. Это уменьшит размер финального образа и даст контроль версии браузера.

Сборка образа выполняется стандартно:

docker build . -t puppeteer:latest

Сборка может занять несколько минут, особенно при медленном интернет-соединении.

Использование Puppeteer в Docker

Даже после установки системных зависимостей поведение окружения в контейнере отличается от обычной ОС. Поэтому при запуске Chromium из контейнера важно передавать дополнительные флаги.

Пример простого скрипта Node.js, который запускает headless Chrome, открывает страницу и делает скриншот:

const puppeteer = require("puppeteer");

(async () => {
  const browser = await puppeteer.launch({
    headless: true,
    args: [
      "--disable-gpu",
      "--disable-dev-shm-usage",
      "--disable-setuid-sandbox",
      "--no-sandbox"
    ]
  });

  const page = await browser.newPage();
  await page.goto("https://example.com");
  const ss = await page.screenshot({ path: "/screenshot.png" });
  await page.close();
  await browser.close();
})();

Короткая расшифровка флагов:

  • –disable-gpu — внутри контейнера обычно нет доступа к GPU. Этот флаг отключает попытки внешнего рендеринга.
  • –no-sandbox и –disable-setuid-sandbox — отключают песочницу Chrome, что часто требуется при запуске от root (по умолчанию в контейнере). Эти флаги снижают уровень безопасности: следите за изоляцией контейнеров. Альтернатива — настроить корректную песочницу внутри контейнера, но это сложнее.
  • –disable-dev-shm-usage — по умолчанию Docker даёт /dev/shm около 64 МБ; Chromium может исчерпать это пространство и падать. С этим флагом Chrome использует /tmp.

Добавьте ваш JavaScript в контейнер командой COPY или другим способом. При корректных флагах браузер должен запускаться без дополнительных трюков.

Когда это не сработает — частые причины и решения

  • Неправильные права на бинарник Chromium: проверьте chmod и владельца файла внутри контейнера.
  • Недостаток памяти: Chromium потребляет много RAM. При множественных инстансах нужно увеличивать лимиты контейнера или использовать пул браузеров.
  • Сломанная или несовместимая версия Chromium: если Puppeteer скачал бинарник, несовместимость редка, но бывает. Отключите авто-скачивание и используйте системный бинарник подходящей версии.
  • Запуск как root без флагов песочницы: либо используйте флаги –no-sandbox/–disable-setuid-sandbox, либо запускайте не от root и корректно настройте песочницу.

Альтернативные подходы

  • Использовать образ headless-shell или готовые Docker-образы с браузером (например, официальные или из trusted-repos), чтобы не собирать зависимости вручную.
  • Рассмотреть Playwright — альтернатива с кросс-браузерной поддержкой и утилитами для CI.
  • Вынести браузерную часть на отдельный сервис (remote browser) и подключаться к нему по WebSocket; тогда контейнеры приложений не будут нести вес браузера.

Чеклист для Dockerfile и CI

  • Базовый образ содержит Node.js или Node устанавливается корректно.
  • Установлены все системные зависимости для Chromium.
  • package.json и package-lock.json копируются и устанавливаются через npm ci.
  • PUPPETEER_SKIP_CHROMIUM_DOWNLOAD настроен при необходимости.
  • Правильные права на node_modules/puppeteer/.local-chromium.
  • В контейнере используется HEALTHCHECK для проверки доступности сервиса, если он должен быть долговечным.
  • В CI ограничьте параллельность запуска браузеров, чтобы не исчерпать память runner’а.

Критерии приёмки

  1. Скрипт успешно запускается в контейнере и делает скриншот целевой страницы без ошибок запуска Chrome.
  2. Размер финального образа не превышает ожидаемый порог (по соглашению команды).
  3. При одновременном запуске N инстансов не наблюдается OOM при выделенных лимитах.
  4. Логи не содержат ошибок прав на бинарник Chromium и проблем с /dev/shm.

Playbook для CI — шаги

  1. Собрать образ с зависимостями и пакетом приложения.
  2. В CI поставить переменные окружения (PUPPETEER_SKIP_CHROMIUM_DOWNLOAD по необходимости).
  3. Запустить контейнер с лимитами CPU и памяти, соответствующими нагрузке.
  4. Выполнить тесты, собирающие скриншоты / проверяющие поведение.
  5. После тестов закрыть браузеры и отдать артефакты (скриншоты) в CI.
  6. Удалить временные контейнеры и образы.

Тесты и критерии приёмки (минимальные тест-кейсы)

  • Запуск скрипта: контейнер стартует, браузер запускается, возвращается код 0.
  • Снимок экрана: screenshot.png существует и имеет размер больше 0 байт.
  • Стресс-тест: 10 последовательных запусков без утечек памяти (локально/CI).
  • Параллельный запуск: N параллельных браузеров с лимитами контейнера — не превышается лимит памяти.

Риски и смягчение

  • Риск: отключение песочницы (–no-sandbox) повышает уязвимость. Мягчение: запускайте контейнеры в доверенной сети, используйте непривилегированные хосты и минимальные права.
  • Риск: исчерпание /dev/shm. Мягчение: использовать –disable-dev-shm-usage или увеличить размер shm (docker run –shm-size=1g).
  • Риск: большой размер образа. Мягчение: отключить скачивание Chromium в npm (PUPPETEER_SKIP_CHROMIUM_DOWNLOAD) и использовать системный бинарник, либо очищать кэш apt и npm после сборки.

Советы по производительности

  • Переиспользуйте экземпляры браузера: запускать один browser и открывать новые страницы быстрее и экономичнее, чем постоянно создавать и закрывать браузеры.
  • Используйте пул страниц/браузеров для параллельных задач.
  • Применяйте ограничение concurrency в вашем коде.
  • Для тяжёлых задач увеличьте лимиты контейнера (CPU и память).

Короткий глоссарий

  • Puppeteer — библиотека Node.js для управления Chrome/Chromium.
  • Chromium — движок браузера, часто поставляется с Puppeteer.
  • headless — режим работы браузера без UI.
  • /dev/shm — раздел общей памяти, используемый Chromium для обмена данными.

Локальные альтернативы и советы для разработчиков в РФ/Европе

  • Для минимизации размера образа и соответствия корпоративным требованиям хранения: отключите автоматическую загрузку Chromium и используйте корпоративный зеркалированный бинарник браузера.
  • В корпоративных CI может быть запрещено запускать контейнеры с –no-sandbox. В этом случае настройте непользовательскую среду или используйте выделенные runner’ы с правильной поддержкой песочницы.

Заключение

Запуск Puppeteer в Docker — задача решаемая, но требует внимания к системным зависимостям, правам на бинарники и правильным флагам запуска. Контролируйте ресурсы и ограничивайте параллелизм для предотвращения исчерпания памяти. Если безопасность критична, уделите время настройке корректной песочницы, вместо постоянного использования –no-sandbox.

Важно: протестируйте образ и поведение в условиях, близких к production, прежде чем включать его в CI или кластер.

Важно: при массовом запуске браузеров рассматривайте архитектуру с выделенным сервисом браузера или пулом для повторного использования инстансов.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Просмотр анимированных GIF на Mac
macOS

Просмотр анимированных GIF на Mac

Режим экономии батареи Windows — включение и настройка
Windows

Режим экономии батареи Windows — включение и настройка

Защита Android от Godfather
Безопасность

Защита Android от Godfather

Виджет Focus Sessions в Windows 11 — что нового
Windows

Виджет Focus Sessions в Windows 11 — что нового

Поиск в Google Workspace: фильтры и приёмы
Поиск Google

Поиск в Google Workspace: фильтры и приёмы

Как проверить мощность USB‑портов в Windows
Оборудование

Как проверить мощность USB‑портов в Windows