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.
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.