Contexte
J'ai construit une application qui utilise Puppeteer sur mon hôte local. Maintenant que j'essaie de le déployer dans un environnement Debian, le script qui exécute Puppeteer a expiré. Après des recherches, j’ai réalisé que c’était un problème courant. La plupart des environnements Debian ne contiennent pas les dépendances nécessaires à l'exécution de Chromium.
Problème
J'ai trouvé des moyens recommandés pour exécuter l'application à l'aide de Docker ici.
Je peux exécuter l'application à l'aide de Docker, mais une fois que j'ai ajouté les données spécifiques à Chrome à mon fichier Docker, quelques erreurs se sont produites.
Échec du déplacement vers un nouvel espace de noms: espaces de noms PID pris en charge, espace de noms Réseau Pris en charge, mais échec: errno = opération non autorisée.
Il est suggéré d'exécuter l'application en tant qu'utilisateur créé dans le fichier Docker. Mais, lorsque j'ajoute cet utilisateur, celui-ci obtient l'erreur mentionnée ci-dessus.
Puis, lorsque j'essaie d'exécuter l'application en tant que root, une nouvelle erreur se produit.
L'exécution en tant que root sans --no-sandbox n'est pas prise en charge.
Bien que cela ne soit pas recommandé, je souhaite que l'application fonctionne même avec --no-sandbox
pour voir si cela fonctionne.
Exemple
J'ai utilisé l'application comme ça,
docker run -p 3000:3000 user/app-name
fichier Docker
FROM ubuntu:16.04
# Application parameters and variables
ENV NODE_ENV=production
ENV PORT=3000
ENV Root_Dir /
ENV application_directory /usr/src/app
ENV font_directory /usr/share/fonts/noto
# Configuration for Chrome
ENV CONNECTION_TIMEOUT=60000
ENV CHROME_PATH=/usr/bin/google-chrome
RUN mkdir -p $application_directory
RUN mkdir -p $font_directory
# Dependencies needed for packages downstream
RUN apt-get update && apt-get install -y \
apt-utils \
unzip \
fontconfig \
locales \
gconf-service \
libasound2 \
libatk1.0-0 \
libc6 \
libcairo2 \
libcups2 \
libdbus-1-3 \
libexpat1 \
libfontconfig1 \
libgcc1 \
libgconf-2-4 \
libgdk-pixbuf2.0-0 \
libglib2.0-0 \
libgtk-3-0 \
libnspr4 \
libpango-1.0-0 \
libpangocairo-1.0-0 \
libstdc++6 \
libx11-6 \
libx11-xcb1 \
libxcb1 \
libxcomposite1 \
libxcursor1 \
libxdamage1 \
libxext6 \
libxfixes3 \
libxi6 \
libxrandr2 \
libxrender1 \
libxss1 \
libxtst6 \
ca-certificates \
fonts-liberation \
libappindicator1 \
libnss3 \
lsb-release \
xdg-utils \
wget
# It's a good idea to use dumb-init to help prevent zombie chrome processes.
ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_AMD64 /usr/local/bin/dumb-init
RUN chmod +x /usr/local/bin/dumb-init
# Install Node.js
RUN apt-get install --yes curl &&\
curl --silent --location https://deb.nodesource.com/setup_8.x | bash - &&\
apt-get install --yes nodejs &&\
apt-get install --yes build-essential
# Install emoji's
RUN cd $font_directory &&\
wget https://github.com/emojione/emojione-assets/releases/download/3.1.2/emojione-Android.ttf &&\
wget https://github.com/googlei18n/noto-cjk/blob/master/NotoSansCJKsc-Medium.otf?raw=true && \
fc-cache -f -v
RUN apt-get update && apt-get install -y wget --no-install-recommends \
&& wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
&& sh -c 'echo "deb [Arch=AMD64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \
&& apt-get update \
&& apt-get install -y google-chrome-unstable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst ttf-freefont \
--no-install-recommends \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get purge --auto-remove -y curl \
&& rm -rf /src/*.deb
# Cleanup
RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Install puppeteer so it's available in the container.
RUN npm i puppeteer
# Add user so we don't need --no-sandbox.
RUN groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
&& mkdir -p /home/pptruser/Downloads \
&& chown -R pptruser:pptruser /home/pptruser \
&& chown -R pptruser:pptruser /node_modules
RUN cd $application_directory
WORKDIR $application_directory
# Install app dependencies
COPY package.json .
# Bundle app source
COPY . .
# Build
RUN npm install
USER pptruser
# Expose the web-socket and HTTP ports
EXPOSE 3000
ENTRYPOINT ["dumb-init", "--"]
CMD ["google-chrome-unstable", "npm", "start"]
Question
Comment puis-je exécuter Docker et passer le,
--no-sandbox
param donc ça va me laisser courir ça en root?
Ou, que dois-je changer dans mon fichier Docker actuel pour qu'il me permette de l'exécuter en tant que USER pptruser
Problèmes actuels -
Courir en tant que
USER pptruser
Échec du déplacement vers un nouvel espace de noms: espaces de noms PID pris en charge, espace de noms Réseau Pris en charge, mais échec: errno = opération non autorisée.
Courir en tant que
root
L'exécution en tant que root sans --no-sandbox n'est pas prise en charge.
Dans votre code nodejs lorsque vous lancez votre navigateur, vous pouvez passer l’argument --no-sandbox
.
exemple:-
const launchBrowser = async () => {
puppetBrowser = await puppeteer.launch({
args: ['--no-sandbox'],
timeout: 10000,
});
};
Il n'y a pas besoin de délai d'attente,
const browser = await puppeteer.launch({headless: true, args:['--no-sandbox']});
Contexte
J'étais l'OP. Des mois ont passé et je continue à voir des gens ayant des problèmes similaires sur Internet. Problèmes Github et SO. Pour cette raison, je souhaite montrer à tous comment j'ai résolu ce problème.
Problème
L'exécution de Puppeteer sur Debian échoue à cause de bibliothèques manquantes.
Solution
J'ai pu exécuter l'application à l'aide d'un fichier Docker et en ajoutant une option de configuration à Puppeteer.
Exemples
Fichier Docker
FROM node:8
ENV Host 0.0.0.0
EXPOSE 8080
RUN apt-get update
# for https
RUN apt-get install -yyq ca-certificates
# install libraries
RUN apt-get install -yyq libappindicator1 libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libnss3 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6
# tools
RUN apt-get install -yyq gconf-service lsb-release wget xdg-utils
# and fonts
RUN apt-get install -yyq fonts-liberation
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY . /usr/src/app
RUN mkdir -p /usr/src/app/views
# install the necessary packages
RUN npm install
CMD npm run start
Marionnettiste
const browser = await puppeteer.launch({
args: ['--no-sandbox', '--disable-setuid-sandbox'],
ignoreHTTPSErrors: true,
dumpio: false
});
J'espère que ça aide. Fondamentalement, lors de l'exécution de l'application, vous installerez les bibliothèques manquantes en configurant votre fichier Docker. Lorsque votre application exécutera les options de configuration transmises à l'objet Puppeteer, elle permettra à votre application de s'exécuter sur Debian.
Je rencontrais un problème similaire en essayant de faire fonctionner Chromium sans tête dans un conteneur Alpine Docker, et il en va apparemment beaucoup d'autres (par exemple, ici , ici ). L'option --no-sandbox
est une solution de contournement simple, mais évidemment une pratique de sécurité médiocre. Ce qui a fonctionné pour moi a été de définir une coutume seccomp
.
Télécharger ce fichier (si intéressé, voir les notes de l'auteur ici ). Puis passez l’option --security-opt seccomp=path/to/chrome.json
au démarrage de Docker ou spécifiez la même option dans votre docker-compose.yml
si vous en utilisez un.