Comment exécuter Puppeteer et Headless Chrome dans un conteneur Docker –
Puppeteer est une bibliothèque Node.js qui vous permet d’interagir avec le navigateur Web Chrome. Les versions récentes incluent également la prise en charge de Firefox.
Puppeteer est couramment utilisé pour automatiser les tests, archiver les données de pages Web et générer des captures d’écran de contenu Web en direct. Il vous permet de contrôler Chrome via une API claire, vous donnant la possibilité de naviguer vers les pages, de cliquer sur les contrôles de formulaire et d’émettre des commandes de navigateur.
Faire fonctionner Puppeteer dans un conteneur Docker peut être complexe car de nombreuses dépendances sont nécessaires pour exécuter Chrome sans tête. Voici comment tout installer pour pouvoir utiliser Puppeteer dans un cluster Kubernetes, dans un conteneur isolé sur votre machine de développement ou dans le cadre d’un pipeline CI.
Sommaire
Les exigences de base
Nous utilisons une image basée sur Debian pour les besoins de cet article. Si vous utilisez une base différente, vous devrez adapter les commandes du gestionnaire de packages affichées en conséquence. L’image officielle Node.js est un point de départ approprié qui signifie que vous n’avez pas besoin d’installer manuellement Node.
Puppeteer est distribué via npm, le gestionnaire de packages Node.js. Il regroupe la dernière version de Chromium dans son package, donc théoriquement un npm install puppeteer
vous ferait courir. En pratique, un environnement Docker propre n’aura pas les dépendances dont vous avez besoin pour exécuter Chrome.
Comme il s’agit généralement d’un programme d’interface graphique lourd, Chrome dépend des bibliothèques de polices, de graphiques, de configuration et de gestion des fenêtres. Tous ces éléments doivent être installés dans votre Dockerfile.
Au moment de la rédaction, la liste de dépendances actuelle ressemble à ceci :
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
Les dépendances sont installées manuellement pour faciliter l’utilisation du binaire Chromium fourni avec Puppeteer. Cela garantit la cohérence entre les versions de Puppeteer et évite la possibilité qu’une nouvelle version de Chrome arrive avec des incompatibilités qui cassent Puppeteer.
Maintenant, cours npm install puppeteer
dans votre répertoire de travail local. Cela créera un package.json
et package-lock.json
pour vous d’utiliser. Dans votre Dockerfile, copiez ces fichiers dans le conteneur et utilisez npm ci
pour installer Marionnettiste.
# (above section omitted) COPY package.json . COPY package-lock.json . RUN npm ci
La dernière étape consiste à rendre le binaire Chromium fourni par Puppeteer correctement exécutable. Sinon, vous rencontrerez des erreurs d’autorisation chaque fois que Puppeteer essaiera de démarrer Chrome.
# (above section omitted) RUN chmod -R o+rwx node_modules/puppeteer/.local-chromium
Vous souhaiterez peut-être installer manuellement une version spécifique de Chrome dans des environnements personnalisés. Réglage de la PUPPETEER_SKIP_CHROMIUM_DOWNLOAD
variable d’environnement avant d’exécuter npm ci
désactivera le téléchargement du navigateur de Puppeteer pendant l’installation. Cela aide à affiner votre image finale.
À ce stade, vous devriez être prêt à construire votre image :
docker build . -t puppeteer:latest
Il s’agit d’un processus de construction assez important qui peut prendre plusieurs minutes avec une connexion Internet plus lente.
Utiliser Puppeteer dans Docker
Certaines considérations particulières s’appliquent au lancement de Chrome lorsque vous utilisez Puppeteer dans un environnement Dockerisé. Malgré l’installation de toutes les dépendances, l’environnement reste différent de la plupart des installations Chrome classiques, des indicateurs de lancement supplémentaires sont donc nécessaires.
Voici un exemple minimal d’utilisation de Puppeteer dans votre conteneur :
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();
Cela montre un script simple qui lance une instance Chrome sans tête, navigue vers une URL et capture une capture d’écran de la page. Le navigateur est alors fermé pour éviter de gaspiller des ressources système.
La section importante est la liste d’arguments transmise à Chromium dans le cadre du launch()
appel:
disable-gpu
– Le GPU n’est généralement pas disponible dans un conteneur Docker, sauf si vous avez spécialement configuré l’hôte. La définition de cet indicateur indique explicitement à Chrome de ne pas essayer d’utiliser le rendu basé sur GPU.no-sandbox
etdisable-setuid-sandbox
– Ceux-ci désactivent le sandboxing de Chrome, une étape qui est requise lors de l’exécution en tant queroot
user (la valeur par défaut dans un conteneur Docker). L’utilisation de ces indicateurs pourrait permettre au contenu Web malveillant d’échapper au processus du navigateur et de compromettre l’hôte. Il est essentiel de vous assurer que vos conteneurs Docker sont fortement isolés de votre hôte. Si vous n’êtes pas à l’aise avec cela, vous devrez configurer manuellement le sandboxing Chrome fonctionnel, qui est un processus plus complexe.disable-dev-shm-usage
– Cet indicateur est nécessaire pour éviter de rencontrer des problèmes avec l’espace mémoire partagé faible par défaut de Docker de 64 Mo. Chrome écrira dans/tmp
au lieu.
Ajoutez votre JavaScript à votre conteneur avec un COPY
instruction. Vous devriez trouver que Puppeteer s’exécute avec succès, à condition que les indicateurs Chrome appropriés soient utilisés.
Conclusion
L’exécution de Puppeteer dans un conteneur Docker vous permet d’automatiser les pages Web dans le cadre de vos pipelines CI et de votre infrastructure de production. Il vous aide également à isoler votre environnement pendant le développement, vous n’avez donc pas besoin d’installer Chrome localement.
Votre conteneur doit avoir les bonnes dépendances installées. Vous devez également définir des arguments de lancement de Chrome pour que le navigateur fonctionne correctement dans votre environnement Dockerisé. Ensuite, vous devriez pouvoir utiliser l’API Puppeteer sans autre considération particulière.
Il convient de prêter attention à l’utilisation des ressources de Chrome. Le lancement de plusieurs navigateurs dans une seule instance de conteneur pourrait rapidement épuiser les limites de mémoire Docker. Augmentez les limites de votre conteneur ou implémentez un système qui restreint la concurrence des scripts ou réutilise les instances de navigateur en cours d’exécution.