Поиск по сайту:

Как запустить Puppeteer и Headless Chrome в контейнере Docker


Puppeteer — это библиотека Node.js, которая позволяет вам взаимодействовать с веб-браузером Chrome. Последние выпуски также включают поддержку Firefox.

Puppeteer обычно используется для автоматизации тестирования, архивирования данных веб-страниц и создания скриншотов живого веб-контента. Он позволяет вам управлять Chrome через понятный API, предоставляя вам возможность переходить на страницы, нажимать на элементы управления формой и выполнять команды браузера.

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

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

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

Puppeteer распространяется через npm, менеджер пакетов Node.js. Он объединяет последнюю сборку Chromium в своем пакете, поэтому теоретически npm install puppeteer заставит вас работать. На практике в чистой среде Docker не будет зависимостей, необходимых для запуска Chrome.

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

На момент написания текущий список зависимостей выглядит так:

FROM node:latest
WORKDIR /puppeteer
RUN 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

Зависимости устанавливаются вручную, чтобы облегчить использование бинарного файла Chromium, который входит в комплект Puppeteer. Это обеспечивает согласованность между выпусками Puppeteer и позволяет избежать появления новых выпусков Chrome с несовместимостями, которые нарушают работу Puppeteer.

Теперь запустите npm install puppeteer в своем локальном рабочем каталоге. Это создаст файлы package.json и package-lock.json, которые вы сможете использовать. В вашем Dockerfile скопируйте эти файлы в контейнер и используйте npm ci для установки Puppeteer.

# (above section omitted)
COPY package.json .
COPY package-lock.json .
RUN npm ci

Последний шаг — сделать двоичный файл Chromium, входящий в комплект Puppeteer, правильно исполняемым. В противном случае вы столкнетесь с ошибками разрешений всякий раз, когда Puppeteer попытается запустить Chrome.

# (above section omitted)
RUN chmod -R o+rwx node_modules/puppeteer/.local-chromium

Возможно, вы захотите вручную установить определенную версию Chrome в настраиваемых средах. Установка переменной среды PUPPETEER_SKIP_CHROMIUM_DOWNLOAD перед запуском npm ci отключит загрузку собственного браузера Puppeteer во время установки. Это поможет уменьшить итоговое изображение.

На этом этапе вы должны быть готовы создать свой образ:

docker build . -t puppeteer:latest

Это довольно большой процесс сборки, который может занять несколько минут при медленном интернет-соединении.

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

Некоторые особенности относятся к запуску Chrome, когда вы используете Puppeteer в Dockerized среде. Несмотря на установку всех зависимостей, среда по-прежнему отличается от большинства обычных установок Chrome, поэтому требуются дополнительные флаги запуска.

Вот минимальный пример использования Puppeteer внутри вашего контейнера:

const puppeteer = require("puppeteer");
 
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();

Это демонстрирует простой скрипт, который запускает безголовый экземпляр Chrome, переходит по URL-адресу и делает снимок экрана со страницей. Затем браузер закрывается, чтобы не расходовать системные ресурсы.

Важным разделом является список аргументов, который передается в Chromium как часть вызова launch():

  • disable-gpu — GPU обычно недоступен внутри контейнера Docker, если вы специально не настроили хост. Установка этого флага явным образом указывает Chrome не пытаться использовать отрисовку на основе графического процессора.
  • no-sandbox и disable-setuid-sandbox — отключают песочницу Chrome, шаг, который требуется при работе в качестве пользователь root (по умолчанию в контейнере Docker). Использование этих флагов может привести к тому, что вредоносный веб-контент выйдет из процесса браузера и скомпрометирует хост. Крайне важно, чтобы ваши контейнеры Docker были строго изолированы от вашего хоста. Если вас это не устраивает, вам нужно вручную настроить рабочую песочницу Chrome, что является более сложным процессом.
  • disable-dev-shm-usage — этот флаг необходим, чтобы избежать проблем с небольшим пространством общей памяти Docker по умолчанию, равным 64 МБ. Вместо этого Chrome будет записывать в /tmp.

Добавьте свой JavaScript в контейнер с помощью инструкции COPY. Вы должны обнаружить, что Puppeteer выполняется успешно, если используются правильные флаги Chrome.

Заключение

Запуск Puppeteer в контейнере Docker позволяет автоматизировать веб-страницы как часть ваших конвейеров непрерывной интеграции и производственной инфраструктуры. Это также помогает вам изолировать вашу среду во время разработки, поэтому вам не нужно устанавливать Chrome локально.

В вашем контейнере должны быть установлены правильные зависимости. Вы также должны установить аргументы запуска Chrome, чтобы браузер правильно работал в вашей среде Dockerized. После этого вы сможете использовать Puppeteer API без каких-либо особых соображений.

Стоит обратить внимание на использование ресурсов Chrome. Запуск нескольких браузеров в одном экземпляре контейнера может быстро исчерпать ограничения памяти Docker. Либо увеличьте ограничения для своего контейнера, либо внедрите систему, которая ограничивает параллелизм сценариев или повторно использует запущенные экземпляры браузера.




Все права защищены. © Linux-Console.net • 2019-2024