So führen Sie Puppeteer und Headless Chrome in einem Docker-Container aus

0
255

Puppeteer ist eine Node.js-Bibliothek, mit der Sie mit dem Chrome-Web interagieren können Browser. Neuere Versionen enthalten auch Firefox-Unterstützung.

Puppeteer wird häufig verwendet, um Tests zu automatisieren, Webseitendaten zu archivieren und Screenshots von Live-Webinhalten zu erstellen. Sie können Chrome über eine klare API steuern, sodass Sie zu Seiten navigieren, auf Formularsteuerelemente klicken und Browserbefehle ausgeben können.

Die Ausführung von Puppeteer in einem Docker-Container kann komplex sein, da viele Abhängigkeiten sind benötigt, um kopfloses Chrome auszuführen. So installieren Sie alles, damit Sie Puppeteer in einem Kubernetes-Cluster, in einem isolierten Container auf Ihrem Entwicklungscomputer oder als Teil einer CI-Pipeline verwenden können.

Die Grundvoraussetzungen

Für die Zwecke dieses Artikels verwenden wir ein Debian-basiertes Image. Wenn Sie eine andere Basis verwenden, müssen Sie die angezeigten Paketmanagerbefehle entsprechend anpassen. Das offizielle Node.js-Image ist ein geeigneter Ausgangspunkt, sodass Sie Node nicht manuell installieren müssen.

Puppeteer wird über npm, den Node.js-Paketmanager, verteilt. Es bündelt die neueste Version von Chromium in seinem Paket, so dass Sie theoretisch ein npm install Puppeteer zum Laufen bringen würde. In der Praxis fehlen einer sauberen Docker-Umgebung die Abhängigkeiten, die Sie zum Ausführen von Chrome benötigen.

Werbung

Da es sich normalerweise um ein schwergewichtiges GUI-Programm handelt, hängt Chrome von Schriftarten-, Grafik-, Konfigurations- und Fensterverwaltungsbibliotheken ab. Diese müssen alle in Ihrem Dockerfile installiert werden.

Zum Zeitpunkt des Schreibens sieht die aktuelle Abhängigkeitsliste so aus:

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 libxcurdamage1 libxcurdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 xdg-utils

Die Abhängigkeiten werden manuell installiert, um die Verwendung der mit Puppeteer gebündelten Chromium-Binärdatei zu erleichtern. Dies stellt die Konsistenz zwischen Puppeteer-Versionen sicher und vermeidet die Möglichkeit, dass eine neue Chrome-Version mit Inkompatibilitäten eintrifft, die Puppeteer beschädigen.

Führen Sie jetzt npm install puppeteer in Ihrem lokalen Arbeitsverzeichnis aus. Dadurch werden eine package.json und eine package-lock.json erstellt, die Sie verwenden können. Kopieren Sie diese Dateien in Ihrem Dockerfile in den Container und verwenden Sie npm ci, um Puppeteer zu installieren.

# (oberer Abschnitt weggelassen) COPY package.json . COPY package-lock.json . RUN npm ci

Der letzte Schritt besteht darin, die gebündelte Chromium-Binärdatei von Puppeteer ordnungsgemäß ausführbar zu machen. Andernfalls treten Berechtigungsfehler auf, wenn Puppeteer versucht, Chrome zu starten.

# (Abschnitt oben weggelassen) RUN chmod -R o+rwx node_modules/puppeteer/.local-chromium

Möglicherweise eine bestimmte Chrome-Version manuell in angepassten Umgebungen installieren. Wenn Sie die Umgebungsvariable PUPPETEER_SKIP_CHROMIUM_DOWNLOAD setzen, bevor Sie npm ci ausführen, wird der eigene Browser-Download von Puppeteer während der Installation deaktiviert. Dies hilft, Ihr endgültiges Bild zu verkleinern.

Werbung

An dieser Stelle sollten Sie bereit sein, Ihr Image zu erstellen:

docker build . -t puppeteer:latest

Dies ist ein ziemlich umfangreicher Build-Prozess, der bei einer langsameren Internetverbindung mehrere Minuten dauern kann.

Verwenden von Puppeteer in Docker

h2>

Beim Starten von Chrome gelten einige Besonderheiten, wenn Sie Puppeteer in einer Dockerized-Umgebung verwenden. Trotz der Installation aller Abhängigkeiten sieht die Umgebung immer noch anders aus als bei den meisten regulären Chrome-Installationen, daher sind zusätzliche Start-Flags erforderlich.

Hier ein minimales Beispiel für die Verwendung von Puppeteer in Ihrem Container:

const puppenspieler = erfordern("puppenspieler");   const browser = warten puppeteer.launch({ ohne Kopf: wahr, Argumente: [ "–disable-gpu", "–disable-dev-shm-usage", "–disable-setuid-sandbox", "–no-sandbox", ] });   const page = wait browser.newPage(); wait page.goto("https://example.com"); const ss = wait page.screenshot({path: "/screenshot.png"});   wait page.close(); warten browser.close();

Dies zeigt ein einfaches Skript, das eine kopflose Chrome-Instanz startet, zu einer URL navigiert und einen Screenshot der Seite aufnimmt. Der Browser wird dann geschlossen, um eine Verschwendung von Systemressourcen zu vermeiden.

Der wichtige Abschnitt ist die Liste der Argumente, die als Teil des launch()-Aufrufs an Chromium übergeben wird:

    < li>GPU deaktivieren– Die GPU ist normalerweise nicht in einem Docker-Container verfügbar, es sei denn, Sie haben den Host speziell konfiguriert. Das Setzen dieses Flags weist Chrome ausdrücklich an, kein GPU-basiertes Rendering zu verwenden.
  • no-sandbox und disable-setuid-sandbox– Diese deaktivieren das Sandboxing von Chrome, ein Schritt, der bei der Ausführung als Root-Benutzer erforderlich ist (der Standardwert in einem Docker-Container). Die Verwendung dieser Flags könnte es bösartigen Webinhalten ermöglichen, dem Browserprozess zu entkommen und den Host zu gefährden. Es ist wichtig, dass Sie sicherstellen, dass Ihre Docker-Container stark von Ihrem Host isoliert sind. Wenn Sie sich damit unwohl fühlen, müssen Sie das funktionierende Chrome-Sandboxing manuell konfigurieren, was ein komplizierterer Prozess ist.
  • disable-dev-shm-usage – Dieses Flag ist erforderlich, um Probleme mit dem standardmäßig niedrigen gemeinsamen Speicherplatz von Docker von 64 MB zu vermeiden. Chrome schreibt stattdessen in /tmp.

Werbung

Fügen Sie Ihr JavaScript mit einer COPY-Anweisung zu Ihrem Container hinzu. Sie sollten feststellen, dass Puppeteer erfolgreich ausgeführt wird, vorausgesetzt, dass die richtigen Chrome-Flags verwendet werden.

Schlussfolgerung

Wenn Sie Puppeteer in einem Docker-Container ausführen, können Sie Webseiten als Teil Ihrer CI-Pipelines automatisieren und Produktionsinfrastruktur. Es hilft Ihnen auch, Ihre Umgebung während der Entwicklung zu isolieren, sodass Sie Chrome nicht lokal installieren müssen.

Auf Ihrem Container müssen die richtigen Abhängigkeiten installiert sein. Sie müssen auch Chrome-Startargumente festlegen, damit der Browser in Ihrer Dockerized-Umgebung ordnungsgemäß funktioniert. Danach sollten Sie die Puppeteer-API ohne weitere Besonderheiten verwenden können.

Es lohnt sich, auf die Ressourcennutzung von Chrome zu achten. Das Starten mehrerer Browser in einer einzelnen Containerinstanz kann die Speichergrenzen von Docker schnell erschöpfen. Erhöhen Sie entweder die Grenzen Ihres Containers oder implementieren Sie ein System, das die Skript-Parallelität einschränkt oder laufende Browser-Instanzen wiederverwendet.