Node.js + Puppeteer on Docker, No usable sandbox Node.js + Puppeteer on Docker, No usable sandbox google-chrome google-chrome

Node.js + Puppeteer on Docker, No usable sandbox


You should pass --no-sandbox, --disable-setuid-sandbox args when launch browser. this is my docker file and small script. it's run successfully.

You can know more about puppeteer with docker by this references.

  1. https://github.com/buildkite/docker-puppeteer
  2. https://github.com/alekzonder/docker-puppeteer

Dockerfile

FROM node:12.18.0RUN  apt-get update \     && apt-get install -y wget gnupg ca-certificates \     && 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 \     # We install Chrome to get all the OS level dependencies, but Chrome itself     # is not actually used as it's packaged in the node puppeteer library.     # Alternatively, we could could include the entire dep list ourselves     # (https://github.com/puppeteer/puppeteer/blob/master/docs/troubleshooting.md#chrome-headless-doesnt-launch-on-unix)     # but that seems too easy to get out of date.     && apt-get install -y google-chrome-stable \     && rm -rf /var/lib/apt/lists/* \     && wget --quiet https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh -O /usr/sbin/wait-for-it.sh \     && chmod +x /usr/sbin/wait-for-it.sh# Install Puppeteer under /node_modules so it's available system-wideADD package.json package-lock.json /RUN npm installCMD ["node", "index.js"]

index.js

const puppeteer = require('puppeteer');(async() => {    const browser = await puppeteer.launch({        args: [            '--no-sandbox',            '--disable-setuid-sandbox'        ]    });    const page = await browser.newPage();    await page.goto('https://www.google.com/', {waitUntil: 'networkidle2'});    browser.close();})();


I found a way that allows the use of chrome sandbox, thanks to usethe4ce's answer in here

Initially i needed to install chrome separately from puppeteer, i edited my Dockerfile as following:

FROM node:12.18.0WORKDIR /home/runner/appADD package*.json ./# Install latest chrome dev package and fonts to support major charsets (Chinese, Japanese, Arabic, Hebrew, Thai and a few others)# Note: this installs the necessary libs to make the bundled version of Chromium that Puppeteer# installs, work.RUN 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/*# Uncomment to skip the chromium download when installing puppeteer. If you do,# you'll need to launch puppeteer with:#     browser.launch({executablePath: 'google-chrome-unstable'})ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true# Install node modulesRUN npm i\    # Add user so we don't need --no-sandbox.    # same layer as npm install to keep re-chowned files from using up several hundred MBs more space    && groupadd -r runner && useradd -r -g runner -G audio,video runner \    && mkdir -p /home/runner/Downloads \    && chown -R runner:runner /home/runner \    && chown -R runner:runner /home/runner/app/node_modulesUSER runnerCMD ["google-chrome-unstable"]

Doing that, error changed from No usable sandbox to:

Failed to move to new namespace: PID namespaces supported, Network namespace supported, but failed: errno = Operation not permitted

Then i followed usethe4ce's answer advices.Docker by default blocks accessibility to some kernel level operations, Seccomp options allow to "unlock" some of those operations that chrome needs to create his own sandbox.So i added this chrome.json file to my repo, and i edited my docker-compose file as following:

version: "3.8"services:  <service name>:    build:      <build options>    init: true    security_opt:       - seccomp=<path to chrome.json file>    [...]

If you are not using a docker-compose file you can run your container using the option --security-opt seccomp=path/to/chrome.json as suggested in the linked answer.

Finally launch the browser using:

await puppeteer.launch({  executablePath: 'google-chrome-unstable'});

Edit:

It is not suitable to use a custom installation of chrome, as its version could not be fully supported by puppeteer.The only version guarantied to work with a specific puppeteer version is the one bundled.

So i suggest using security_opt as above, just ignore the custom installation part.