Для работы 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 нужно запускать 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-образы с Node.js и Chromium могут быть достаточно большими, поэтому применяются следующие подходы:
rm -rf
/var/lib/apt/lists/*).
Пример 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. 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 обеспечивает порядок запуска сервисов.
Для отладки Puppeteer в Docker полезно:
–headless=false и подключением к удаленному дисплею.
page.on(‘console’) и
page.on(‘pageerror’).
ldd /usr/bin/chromium внутри контейнера.
networkidle2 или networkidle0 при
навигации страниц, чтобы дождаться полной загрузки ресурсов.