Создание Docker образа с Puppeteer

Для работы Puppeteer в контейнере Docker необходимо учитывать зависимость библиотеки от системных библиотек и браузера Chromium. Puppeteer поставляется с собственной версией Chromium, но для корректной работы в Linux контейнере требуются дополнительные пакеты.

Базовым образом часто используют node:20-slim или node:20-bullseye-slim, так как они обеспечивают легковесное окружение Node.js с возможностью установки необходимых зависимостей.

Пример базового Dockerfile:

FROM node:20-bullseye-slim


RUN apt-get update && apt-get install -y \
    ca-certificates \
    fonts-liberation \
    libasound2 \
    libatk1.0-0 \
    libatk-bridge2.0-0 \
    libcups2 \
    libdbus-1-3 \
    libdrm2 \
    libx11-xcb1 \
    libxcomposite1 \
    libxdamage1 \
    libxrandr2 \
    libgbm1 \
    libpango1.0-0 \
    libxshmfence1 \
    libnss3 \
    libxss1 \
    libxext6 \
    wget \
    unzip \
    --no-install-recommends \
    && rm -rf /var/lib/apt/lists/*

# Создание рабочей директории
WORKDIR /app

# Копирование package.json и package-lock.json
COPY package*.json ./

# Установка зависимостей
RUN npm install

# Копирование исходного кода
COPY . .

# Задание команды по умолчанию
CMD ["node", "index.js"]

Настройка Puppeteer для работы в Docker

Внутри контейнера Puppeteer нужно запускать Chromium с параметрами, отключающими использование GPU и sandbox, так как стандартный sandbox может не работать в Docker без дополнительных привилегий.

Пример конфигурации запуска браузера:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
    headless: true,
    args: [
      '--no-sandbox',
      '--disable-setuid-sandbox',
      '--disable-dev-shm-usage',
      '--disable-accelerated-2d-canvas',
      '--disable-gpu',
      '--window-size=1920,1080'
    ],
  });

  const page = await browser.newPage();
  await page.goto('https://example.com', { waitUntil: 'networkidle2' });
  const content = await page.content();

  console.log(content);

  await browser.close();
})();

Ключевые моменты:

  • –no-sandbox и –disable-setuid-sandbox обязательны для запуска Chromium в контейнере без root-прав.
  • –disable-dev-shm-usage решает проблему ограниченного размера /dev/shm в контейнере, что предотвращает падение браузера.
  • Настройка headless: true уменьшает потребление ресурсов и ускоряет выполнение тестов.

Оптимизация размера Docker-образа

Docker-образы с Node.js и Chromium могут быть достаточно большими, поэтому применяются следующие подходы:

  1. Использование multi-stage сборки. В первом этапе устанавливаются все зависимости и Chromium, во втором копируются только необходимые файлы и бинарники.
  2. Очистка временных файлов после установки пакетов (rm -rf /var/lib/apt/lists/*).
  3. Минимизация количества установленных системных пакетов.

Пример multi-stage Dockerfile:

# Этап сборки
FROM node:20-bullseye-slim AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .

# Этап финального образа
FROM node:20-bullseye-slim
WORKDIR /app
COPY --from=builder /app ./
RUN apt-get update && apt-get install -y \
    ca-certificates \
    fonts-liberation \
    libasound2 \
    libatk1.0-0 \
    libcups2 \
    libdbus-1-3 \
    libx11-xcb1 \
    libxcomposite1 \
    libxdamage1 \
    libxrandr2 \
    libgbm1 \
    libpango1.0-0 \
    libxshmfence1 \
    libnss3 \
    libxss1 \
    libxext6 \
    --no-install-recommends \
    && rm -rf /var/lib/apt/lists/*
CMD ["node", "index.js"]

Работа с Docker Compose

Для организации тестовой среды с несколькими сервисами удобно использовать Docker Compose. Puppeteer контейнер можно связать с базой данных или веб-сервисом для интеграционных тестов.

Пример docker-compose.yml для запуска Puppeteer вместе с тестовым сервером:

version: '3.9'
services:
  puppeteer:
    build: .
    volumes:
      - ./screenshots:/app/screenshots
    depends_on:
      - web
  web:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./public:/usr/share/nginx/html:ro

Ключевые аспекты:

  • Монтирование тома позволяет сохранять скриншоты и результаты тестов на хост-машине.
  • depends_on обеспечивает порядок запуска сервисов.
  • Использование легковесного Nginx образа для локального сервера ускоряет тестирование.

Особенности отладки в контейнере

Для отладки Puppeteer в Docker полезно:

  1. Запускать контейнер с включенным GUI через VNC или с использованием –headless=false и подключением к удаленному дисплею.
  2. Логировать ошибки браузера с помощью page.on(‘console’) и page.on(‘pageerror’).
  3. Проверять наличие всех необходимых библиотек для Chromium через ldd /usr/bin/chromium внутри контейнера.

Рекомендации по стабильности

  • Использовать фиксированные версии Puppeteer и Node.js, чтобы избежать несовместимостей.
  • Применять networkidle2 или networkidle0 при навигации страниц, чтобы дождаться полной загрузки ресурсов.
  • Очистка ресурсов: закрытие страниц и браузера после теста предотвращает утечки памяти и зависания контейнера.