Comment exécuter Puppeteer et Headless Chrome dans un conteneur Docker

0
310

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 des pages Web et générer des captures d'écran du 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.

L'exécution de Puppeteer dans un conteneur Docker peut être complexe car de nombreuses dépendances sont nécessaire 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.

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 paquets affichées en conséquence. L'image officielle de Node.js est un bon point de départ, ce 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 marionnettiste d'installation de npm vous permettrait de fonctionner. En pratique, un environnement Docker propre n'aura pas les dépendances dont vous avez besoin pour exécuter Chrome.

Publicité

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. Ceux-ci doivent tous ê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 libxcurdamor1 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, exécutez npm install puppeteer dans votre répertoire de travail local. Cela créera un package.json et un package-lock.json que vous pourrez utiliser. Dans votre Dockerfile, copiez ces fichiers dans le conteneur et utilisez npm ci pour installer Puppeteer.

# (section ci-dessus omise) COPY package.json . COPIER 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.

# (section ci-dessus omise) RUN chmod -R o+rwx node_modules/puppeteer/.local-chromium

Vous voudrez peut-être installer manuellement une version spécifique de Chrome dans des environnements personnalisés. La définition de la variable d'environnement PUPPETEER_SKIP_CHROMIUM_DOWNLOAD avant d'exécuter npm ci désactivera le téléchargement du propre navigateur de Puppeteer pendant l'installation. Cela aide à affiner votre image finale.

Publicité

À ce stade, vous devriez être prêt à créer 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 marionnettiste = require("marionnettiste");   const browser = wait puppeteer.launch({ sans tête : vrai, arguments : [ “–disable-gpu”, “–disable-dev-shm-usage”, “–disable-setuid-sandbox”, “–no-sandbox”, ] });   const page = wait browser.newPage(); attendez la page.goto("https://example.com"); const ss = wait page.screenshot({chemin : "/screenshot.png"});   attendre la page.close(); wait browser.close();

Ceci illustre un script simple qui lance une instance Chrome sans écran, accède à 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 des arguments qui est transmise à Chromium dans le cadre de l'appel launch() :

    < li>désactiver-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 et disable-setuid-sandbox– Ceux-ci désactivent le sandboxing de Chrome, une étape requise lors de l'exécution en tant qu'utilisateur root (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 à la place.

Publicité

Ajoutez votre JavaScript à votre conteneur avec une instruction COPY. 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 infrastructures de production. Il vous aide également à isoler votre environnement pendant le développement, de sorte que vous n'avez 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 simultanéité des scripts ou réutilise les instances de navigateur en cours d'exécution.