Attempting to run Puppeteer, a Node library to control a headless Chromium (in order to do things like create a PDF of a website), in Docker is a surprisingly fiddly thing.

The problem is that, from my understanding, to run as root, you need the option --no-sandbox, which is rightly decried as being an insecure and bad solution. The problem is that the go-to alternatives seem to be just as bad:

  • Running the container with CAP_ADD=SYS_ADMIN, which I think I needn't comment further, or

  • Running as non-root, but to run Puppeteer in a non-root sandbox, you need to enable the kernel option unprivileged_userns_clone, which once I started researching found it was said to

"open[s] up severe vulnerabilities in the Linux kernel" (link)

as well as

"Unprivileged user namespaces are extremely dangerous" (link)

I am surprised that doing something as simple and comparatively low level as running a web browser seems to require such wide ranging permissions that apparently open up wide swathes of attack vectors. The kind of warnings I'm reading are what I would expect to read if I were to root a phone or compromise the operating systems security routines.

Am I misunderstanding the situation here, or is to run Chromium in a Docker container tantamount to opening up my server to half the internet ?

3 Answers 3


It looks like the best option is to use a custom seccomp profile

You can see an example here

Other links to the file you need in case they disappear:

wget https://raw.githubusercontent.com/jfrazelle/dotfiles/master/etc/docker/seccomp/chrome.json
wget https://raw.githubusercontent.com/Zenika/alpine-chrome/master/chrome.json

Sample usage:

docker container run -it --rm --security-opt seccomp=$(pwd)/chrome.json zenika/alpine-chrome
  • How do you do this on Google Cloud Run? You can't call docker run on there....
    – Lance
    Feb 12 at 23:34

I had the same question and ran into the same scary-sounding answers/comments here on stackexchange. After reading the lwn.net article linked in another answer, and reading all the apparently-relevant answers here on stackexchange, I think I have made sense of the issue.

The problem seems to be that creating an isolated environment involves cloning a "user namespace." With the default setting of unprivileged_userns_clone=0 you can clone a namespace once, however, once inside the namespace it's not possible to further clone the namespace again. Since both docker and chrome create a sandboxed namespace, it's not possible to run chrome from inside a docker container without jumping through additional hoops. Note that the same issue arises when running an electron app which is packaged as an AppImage.

So to answer the specific question posed here: no I don't think it's tantamount to opening up your server to half the internet, though setting unprivileged_userns_clone=1 is not the most secure option.

It seems there are three ways to get around the problem:

  1. Run chrome (or electron) with --no-sandbox. This is probably ok since docker is already providing a level of isolation.
  2. Set up a custom seccomp profile as suggested by another answer.
  3. Override the default kernel.unprivileged_userns_clone setting in your kernel to allow nested namespace cloning. This is the allegedly dangerous activity. It seems that disabling unprivileged_userns_clone is a hardening measure which prevents a class of unknown but potential vulnerabilities that could and probably do exist to some extent. So it's probably not an absolutely glaring security risk. It weakens security to some extent but it doesn't appear to expose you to an immediate and known "in-the-wild" security threat.

The short version: I agree with this answer but I couldn't vote that answer up because I don't yet have enough reputation.


I don't think that running puppeteer as a non-root user requires any modification of the configuration of the underlying host, as there are a number of Docker images which do this successfully.

One example is Decktape which is built on top of Puppeteer. The Docker image (which has commands linked in the GH repo) runs as the user node and works on an unmodified Linux instance.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .