New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chrome Headless doesn't launch on Debian #290

Open
fortes opened this Issue Aug 16, 2017 · 145 comments

Comments

Projects
None yet
@fortes

fortes commented Aug 16, 2017

Running this example code from the README:

const puppeteer = require('puppeteer');

(async() => {

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({path: 'example.png'});

browser.close();
})();

I get the following error output:

(node:30559) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: Failed to connect to chrome!
(node:30559) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Platform info:

% uname -a
Linux localhost 3.14.0 #1 SMP PREEMPT Thu Jul 13 12:08:15 PDT 2017 x86_64 GNU/Linux
% lsb_release -a
Distributor ID: Debian
Description:    Debian GNU/Linux 9.0 (stretch)
Release:        9.0
Codename:       stretch
% node --version
v8.1.1
% cat package.json
{
  "dependencies": {
    "puppeteer": "^0.9.0"
  }
}
@Garbee

This comment has been minimized.

Contributor

Garbee commented Aug 16, 2017

This is working fine here on Elementary OS. I'm downloading a Debian installer now to try this out in a VM.

@aslushnikov

This comment has been minimized.

Contributor

aslushnikov commented Aug 16, 2017

That's interesting. Could you please:

  1. try launching chromium manually (chromium is downloaded at node_modules/puppeteer/.local-chromium)
  2. if chromium launches for you, run the following (notice the added dumpio flag to the puppeteer.launch) and check what's in the stderr:
const puppeteer = require('puppeteer');
(async() => {
  const browser = await puppeteer.launch({dumpio: true});
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});
  browser.close();
})();
@fortes

This comment has been minimized.

fortes commented Aug 16, 2017

Can't launch the local chrome:

% ~/p /home/fortes/p/node_modules/puppeteer/.local-chromium/linux-494755/chrome-linux/chrome --help
/home/fortes/p/node_modules/puppeteer/.local-chromium/linux-494755/chrome-linux/chrome: error while loading shared libraries: libX11-xcb.so.1: cannot open shared object file: No such file or directory

I should have mentioned that this is a headless machine that I'm ssh'd into. Given that this is for headless Chrome, I assume that scenario is still supported?

@Garbee

This comment has been minimized.

Contributor

Garbee commented Aug 16, 2017

I think in the case of Debian systems you still need https://packages.debian.org/sid/libx11-xcb1 to run headless. That way the system has some of the API calls it needs to to do the rendering calculations.

@Garbee

This comment has been minimized.

Contributor

Garbee commented Aug 16, 2017

The action to resolve this (which I'm working on now) is getting a list of all the required dependencies to run Chromium. Straight from the Debian the requirements are below. Documenting this for a PR shortly.

Dependencies for debian
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
@fortes

This comment has been minimized.

fortes commented Aug 16, 2017

Already have that installed, perhaps a different package is needed?

% ~/p sudo apt-get install libx11-xcb1
Reading package lists... Done
Building dependency tree
Reading state information... Done
libx11-xcb1 is already the newest version (2:1.6.4-3).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.
@aslushnikov

This comment has been minimized.

Contributor

aslushnikov commented Aug 16, 2017

@fortes so do dependencies from #290 (comment) help?

@fortes

This comment has been minimized.

fortes commented Aug 16, 2017

I've installed those and can now run chrome --help. However, if I try to run chrome -v, I get the following:

febian:~/p /home/fortes/p/node_modules/puppeteer/.local-chromium/linux-494755/chrome-linux/chrome -v
[11104:11104:0816/105455.434188:FATAL:zygote_host_impl_linux.cc(123)] No usable sandbox! Update your kernel or see https://chromium.googlesource.com/chromium/src/+/master/docs/linux_suid_sandbox_development.md for more information on developing with the SUID sandbox. If you want to live dangerously and need an immediate workaround, you can try using --no-sandbox.
#0 0x556f97804657 base::debug::StackTrace::StackTrace()
#1 0x556f97818311 logging::LogMessage::~LogMessage()
#2 0x556f96a091f1 content::ZygoteHostImpl::Init()
#3 0x556f966a3da0 content::BrowserMainLoop::EarlyInitialization()
#4 0x556f966aa4c3 content::BrowserMainRunnerImpl::Initialize()
#5 0x556f966a3532 content::BrowserMain()
#6 0x556f9750f7fd content::ContentMainRunnerImpl::Run()
#7 0x556f97517314 service_manager::Main()
#8 0x556f9750e462 content::ContentMain()
#9 0x556f9614eb74 ChromeMain
#10 0x7fa1f27c92b1 __libc_start_main
#11 0x556f9614e9d0 <unknown>

Received signal 6
#0 0x556f97804657 base::debug::StackTrace::StackTrace()
#1 0x556f978041cf base::debug::(anonymous namespace)::StackDumpSignalHandler()
#2 0x7fa1f8b690c0 <unknown>
#3 0x7fa1f27dbfcf gsignal
#4 0x7fa1f27dd3fa abort
#5 0x556f97803202 base::debug::BreakDebugger()
#6 0x556f978187cc logging::LogMessage::~LogMessage()
#7 0x556f96a091f1 content::ZygoteHostImpl::Init()
#8 0x556f966a3da0 content::BrowserMainLoop::EarlyInitialization()
#9 0x556f966aa4c3 content::BrowserMainRunnerImpl::Initialize()
#10 0x556f966a3532 content::BrowserMain()
#11 0x556f9750f7fd content::ContentMainRunnerImpl::Run()
#12 0x556f97517314 service_manager::Main()
#13 0x556f9750e462 content::ContentMain()
#14 0x556f9614eb74 ChromeMain
#15 0x7fa1f27c92b1 __libc_start_main
#16 0x556f9614e9d0 <unknown>
  r8: 0000000000000000  r9: 00007fff8e2bda50 r10: 0000000000000008 r11: 0000000000000246
 r12: 00007fff8e2be160 r13: 000000000000016d r14: 00007fff8e2be158 r15: 00007fff8e2be150
  di: 0000000000000002  si: 00007fff8e2bda50  bp: 00007fff8e2bdd00  bx: 0000000000000006
  dx: 0000000000000000  ax: 0000000000000000  cx: 00007fa1f27dbfcf  sp: 00007fff8e2bdac8
  ip: 00007fa1f27dbfcf efl: 0000000000000246 cgf: 002b000000000033 erf: 0000000000000000
 trp: 0000000000000000 msk: 0000000000000000 cr2: 0000000000000000
[end of stack trace]
Calling _exit(1). Core file will not be generated.
@Garbee

This comment has been minimized.

Contributor

Garbee commented Aug 16, 2017

Check the sandbox docs linked to in that error and see if they can help you get it working. Either the security sandbox is messed up on Debian right now or something funky is happening to trigger it to need a non-kernel one. I'm looking into this once this VM server gets installed.

@aslushnikov

This comment has been minimized.

Contributor

aslushnikov commented Aug 16, 2017

This should be solved with the '--no-sandbox' flag:

const puppeteer = require('puppeteer');
(async() => {
  const browser = await puppeteer.launch({args: ['--no-sandbox']});
  const page = await browser.newPage();
  await page.goto('https://example.com');
  await page.screenshot({path: 'example.png'});
  browser.close();
})();
@paulirish

This comment has been minimized.

Member

paulirish commented Aug 16, 2017

It's worth considering adding both --no-sandbox --disable-setuid-sandbox to the default flags on linux.

In chrome-launcher/lighthouse we're already including --disable-setuid-sandbox and plan to add --no-sandbox soon for this reason.

@Garbee

This comment has been minimized.

Contributor

Garbee commented Aug 16, 2017

I have always strongly urged people to never turn off the sandbox without a good cause, even in tests. It is a major part of the security system from what I understand.

I'm setting up a squeaky clean and fresh Debian VM to run some install steps in. We should be able to have it well documented how to get it operating without compromising system security.

I recall PHPStorm for example having an issue where it was serving on localhost, so a remote code execution exploit was opened up for any site including code that would look for the port in use and take advantage of a flaw in that server. Let's not open people up to security issues by disabling the sandbox here. Where they could be visiting any number of sites including code that looks for exploits to abuse.

@aslushnikov aslushnikov changed the title from Unhandled Promise Rejection to Chrome Headless doesn't launch on Debian Aug 16, 2017

@fortes

This comment has been minimized.

fortes commented Aug 16, 2017

Still no luck w/ those two flags:

febian:~/p /home/fortes/p/node_modules/puppeteer/.local-chromium/linux-494755/chrome-linux/chrome --no-sandbox --disable-setuid-sandbox

(chrome:12521): Gtk-WARNING **: cannot open display:
[0816/111850.260959:ERROR:nacl_helper_linux.cc(310)] NaCl helper process running without a sandbox!
Most likely you need to configure your SUID sandbox correctly

Same warning when just with --no-sandbox

@Garbee

This comment has been minimized.

Contributor

Garbee commented Aug 16, 2017

Just as a quick update, I'm like 20-40ish minutes out from starting on testing the install procedure. Downloading packages now for a fresh net install of Debian 9. So, I should get back to you shortly with exact steps to reproduce. It just won't be as fast as something that doesn't require a full OS install. 😄

@fortes

This comment has been minimized.

fortes commented Aug 16, 2017

Thanks for going through effort @Garbee! Will you be testing a headless Debian install, or using via ssh?

@Garbee

This comment has been minimized.

Contributor

Garbee commented Aug 16, 2017

SSH is not relevant to the problem. Only a Debian server without any X/wayland system pre-installed (like any remote web server) will be enough to fully recreate the problem and steps to reproduce. So, that's what I'll be working with locally in a VM.

@maxschmeling

This comment has been minimized.

maxschmeling commented Aug 16, 2017

This may or may not be helpful...

I run Electron in a Docker instance on Docker Cloud.

I run this command:

xvfb-run -a --server-args="-screen 0 1024x1024x24" ./node_modules/.bin/electron ./index.js

and my Dockerfile contains the following commands to install dependencies:

RUN apt-get update -y -q
RUN apt-get install -y -q xvfb libgtk2.0-0 libxtst6 libxss1 libgconf-2-4 libnss3 libasound2
@Garbee

This comment has been minimized.

Contributor

Garbee commented Aug 16, 2017

headless exists to not need xvfb to virtualize the X instance for Chrome. Since it is all done in software internally.

@maxschmeling

This comment has been minimized.

maxschmeling commented Aug 16, 2017

@Garbee awesome. This stuff isn't my strong suit.

I'm going to attempt to replace the Electron usage with puppeteer, so hopefully this will simplify our environment.

@Garbee

This comment has been minimized.

Contributor

Garbee commented Aug 16, 2017

@fortes Are you running this as root by chance?

@Garbee

This comment has been minimized.

Contributor

Garbee commented Aug 16, 2017

If you're running as root (after having all the required deps installed as listed earlier) you need to run without a sandbox since Chromium requires that (no clue why exactly yet.) If running as a normal user, then it should run just fine on a fresh debian install with the required dependencies.

@fortes

This comment has been minimized.

fortes commented Aug 16, 2017

Not running as root

@Garbee

This comment has been minimized.

Contributor

Garbee commented Aug 16, 2017

That's interesting. I setup a fresh Linode box on Debian 9. Installed the packages listed above, then setup nodesource to install node 8. Then the yarn repository. New folder, yarn add puppeteer and then created the index.js and ran it. Everything works perfectly fine without a sandbox error.

Is the box you're running on under you complete control or is it someone else's like a VPS/shared host? If it is a remote host could you share the provider so I can look into if they do anything funny with their kernel configurations.

@Garbee

This comment has been minimized.

Contributor

Garbee commented Aug 16, 2017

Ah yea, that's it. Your box host is messing you up. It has a very old Kernel. Debian 9 ships with 4.9.0-3 and you're running 3.14.0. So the security features of the kernel are extremely different. So, you may be in a case where you need to fallback to using the older file-based sandbox to have some level of security.

Although, in all honesty... Upgrade the kernel or get a host that doesn't keep you back. It's very important that the kernel gets updated for the best security and you're being left vulnerable.

@Garbee

This comment has been minimized.

Contributor

Garbee commented Aug 16, 2017

@fortes If you could, please try running this script on your server to see if you have user namespacing enabled. https://gist.githubusercontent.com/Garbee/dfd33ba0a62f1cbc023b8d57de18efca/raw/f82ed513014062554a3536980a67390b57f1f858/user-namespace-check-linux.sh

@mrbar42

This comment has been minimized.

mrbar42 commented Aug 16, 2017

for the dockerisers amongst us - i've launched successfully with this setup:

FROM node:8

RUN apt-get update && \
apt-get install -yq 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

RUN npm i puppeteer

RUN echo "\
const puppeteer = require('puppeteer');\n\
(async () => {\n\
  const browser = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox']});\n\
  const page = await browser.newPage();\n\
  await page.goto('https://example.com');\n\
  await page.screenshot({path: 'example.png'});\n\
  browser.close();\n\
})();\
" > index.js

CMD ["node", "index.js"]
@Garbee

This comment has been minimized.

Contributor

Garbee commented Aug 16, 2017

PR #311 is open to start looking at expanding the install script to make it much more interactive and friendly to help catch installation problems. You can check the code out from that PR and give it a spin. Please report on the PR of any problems you face or things you think could improve the flow.

kowalcj0 added a commit to uktrade/directory-periodic-tests that referenced this issue Jun 27, 2018

kowalcj0 added a commit to uktrade/directory-periodic-tests that referenced this issue Jun 27, 2018

@shobhitsharma

This comment has been minimized.

shobhitsharma commented Jul 10, 2018

To resolve sandbox security issue, the server sysctl needs to have kernel.unprivileged_userns_clone=1 flag enabled.

For other issues, make sure all required dependencies are installed from this list.

@Aetheryx

This comment has been minimized.

Aetheryx commented Jul 23, 2018

For anyone experiencing the same NaCl helper process running without a sandbox error with the sandbox flags and all of the proper dependencies - make sure you aren't accidentally running with headless: false. Running with that parameter gave me the same error (totally didn't take me an hour to figure it out 🙃)

@dorin131

This comment has been minimized.

dorin131 commented Jul 30, 2018

Just add this to your Dockerfile

RUN apt-get update && apt-get install -y chromium-browser

ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true

This will install Chromium with all the necessary dependencies and then we let Puppeteer know that it doesn't need to re-download Chromium.

Then in your code, launch Puppeteer like so

puppeteer.launch({executablePath: '/usr/bin/chromium-browser'})
@jsanjay63

This comment has been minimized.

jsanjay63 commented Aug 3, 2018

@Aetheryx Thanks, it works in headless mode. But, what if I want to run it in headful mode. Do you have any suggestion?

@Aetheryx

This comment has been minimized.

Aetheryx commented Aug 4, 2018

@jsanjay63 Well, I assume the error would be happening because there is no desktop environment to display Chrome in. Do you have a DE set up on your machine?

@iostack

This comment has been minimized.

iostack commented Aug 7, 2018

Maybe it can help someone , but for me on debian 9 I had to enable namespace in kernel :
Enable user namespaces in Debian kernel
echo 1 > /proc/sys/kernel/unprivileged_userns_clone

@zhaopengme

This comment has been minimized.

zhaopengme commented Aug 9, 2018

try this code on ubuntu server. i'm ok.

 sudo apt-get install -y 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
@GregTexas

This comment has been minimized.

GregTexas commented Aug 15, 2018

Has anyone with Debian 9 solved " UnhandledPromiseRejectionWarning: Error: Failed to launch chrome!"?

@samholmes

This comment has been minimized.

samholmes commented Aug 29, 2018

I did what @slominskir did and it solved my problem:

cd <project-dir-path>/node_modules/puppeteer/.local-chromium/linux-579032/chrome-linux/
sudo chown root:root chrome_sandbox
sudo chmod 4755 chrome_sandbox
sudo ln -s chrome_sandbox /usr/local/sbin/chrome_sandbox

Then I added this line to my .bash_profile:

export CHROME_DEVEL_SANDBOX=/usr/local/sbin/chrome_sandbox

Could someone explain to me why this works or what it does? Is it allowing chrome_sandbox to run as root? I thought that it's bad to run things as root?

@Guruhbk

This comment has been minimized.

Guruhbk commented Aug 29, 2018

Hi. Puppeteer works fine if I install all the required library files to the system(eg.libX11-xcb.so). Is there anyway can I use the puppeteer without installing any dependencies library in the system? BTW I'm using ubuntu 16.

@pirmax

This comment has been minimized.

pirmax commented Aug 29, 2018

Hi,

I've this error despite all your help:

pirmax@debian:~/tests/Puppeteer$ node index.js 
(node:19783) UnhandledPromiseRejectionWarning: Error: Failed to launch chrome!

(chrome:19793): Gtk-WARNING **: cannot open display: 
[0829/111428.811826:ERROR:nacl_helper_linux.cc(310)] NaCl helper process running without a sandbox!
Most likely you need to configure your SUID sandbox correctly


TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md

    at onClose (/home/pirmax/tests/Puppeteer/node_modules/puppeteer/lib/Launcher.js:299:14)
    at Interface.helper.addEventListener (/home/pirmax/tests/Puppeteer/node_modules/puppeteer/lib/Launcher.js:288:50)
    at Interface.emit (events.js:185:15)
    at Interface.close (readline.js:379:8)
    at Socket.onend (readline.js:152:10)
    at Socket.emit (events.js:185:15)
    at endReadableNT (_stream_readable.js:1101:12)
    at process._tickCallback (internal/process/next_tick.js:114:19)
(node:19783) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:19783) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
pirmax@debian:~/tests/Puppeteer$
@bamarch

This comment has been minimized.

bamarch commented Oct 8, 2018

Hopefully this helps everyone running Debian.

The following works for me on Debian Jessie (without disabling sandbox!).

  1. Dependencies.
  1. Puppeteer needs the following kernel feature enabled "user namespacing" (if you want to run without disabling sandbox).
  • Check your kernel supports the feature (it does if this shows CONFIG_USER_NS=y)
    cat /boot/config-$(uname -r) | grep CONFIG_USER_NS
  • Command to permanently enable:
    sudo su; echo 'kernel.unprivileged_userns_clone=1' > /etc/sysctl.d/00-local-userns.conf; service procps restart
  • Note: it is disabled by default in Debian Jessie because of a local security issue.
    This is safely patched as of 3.16.51-3+deb8u1 (see https://security-tracker.debian.org/tracker/CVE-2017-17448)
@Jeedify

This comment has been minimized.

Jeedify commented Oct 12, 2018

@bamarch
This worked for me on a machine running Debian Stretch with 4.9.110-3+deb9u5.
Thank you very much for sharing this.

@abdulmoizeng

This comment has been minimized.

abdulmoizeng commented Oct 24, 2018

Doing both of the following fix it for me

Installing following dependencies (thanks @zhaopengme )
sudo apt-get install -y 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

launching in no sandbox mode

const browser = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox']});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment