Background
I built an application that uses Puppeteer on my localhost. Now that I am trying to deploy it into a debian environment the script that runs Puppeteer is timing out. After researching it I realized it is a common problem. Most debian environments are missing the dependencies needed to run Chromium.
Problem
I found some recommended ways to run the application using Docker here.
I can run the application using Docker, but once I add the Chrome specific data to my Docker file I am getting a few errors.
Failed to move to new namespace: PID namespaces supported, Network namespace supported, but failed: errno = Operation not permitted
It is suggested to run the app as a user made in the Docker file. But, when I add that user, the user gets the error mentioned above.
Then when I try and run the application as root, I get a new error,
Running as root without --no-sandbox is not supported.
Although it is not recommended, I want to get the app running even with --no-sandbox
to see if it works.
Example
I have been running the application like this,
docker run -p 3000:3000 user/app-name
Docker File
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
How do I run Docker and pass the ,
--no-sandbox
param so it will let me run this in root?
Or, what do I need to change in my current Docker file so it will let me run it as the USER pptruser
Current Problems -
Runnning as
USER pptruser
Failed to move to new namespace: PID namespaces supported, Network namespace supported, but failed: errno = Operation not permitted
Running as
root
Running as root without --no-sandbox is not supported.
There is no need of a timeout,
const browser = await puppeteer.launch({headless: true, args:['--no-sandbox']});
In your nodejs code when you launch your browser, you can pass the
--no-sandbox
argument.example:-
Background
I was the OP. Months have went by and I continue to see people having similar problems all over the internet. Github issues and SO. Due to that I want to show everyone how I solved this issue.
Problem
Running Puppeteer on Debian fails due to missing libs.
Solution
I was able to run the application using a Docker file and adding a config option to Puppeteer.
Examples
Docker File
Puppeteer
I hope this helps. Basically when running the app you will install the missing libs by configuring your Docker file then when your app is running the config options passed to the Puppeteer object will allow your app to run on Debian.
I was hitting a similar problem trying to run Chromium headless in an Alpine Docker container, and apparently so are many other (e.g., here, here). The
--no-sandbox
option is a straightforward workaround but obviously a poor security practice. What worked for me was setting a customseccomp
.Download this file (if interested, see the author's notes here). Then pass the option
--security-opt seccomp=path/to/chrome.json
when starting Docker, or specify the same option in yourdocker-compose.yml
if you're using one.