Skip to content
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

Closed
fortes opened this issue Aug 16, 2017 · 173 comments

Comments

Projects
None yet
@fortes
Copy link

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.

Copy link
Contributor

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.

Copy link
Collaborator

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.

Copy link
Author

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.

Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Author

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.

Copy link
Collaborator

commented Aug 16, 2017

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

@fortes

This comment has been minimized.

Copy link
Author

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.

Copy link
Contributor

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.

Copy link
Collaborator

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.

Copy link
Member

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.

Copy link
Contributor

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 Unhandled Promise Rejection Chrome Headless doesn't launch on Debian Aug 16, 2017

@fortes

This comment has been minimized.

Copy link
Author

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.

Copy link
Contributor

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.

Copy link
Author

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.

Copy link
Contributor

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.

Copy link

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.

Copy link
Contributor

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.

Copy link

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.

Copy link
Contributor

commented Aug 16, 2017

@fortes Are you running this as root by chance?

@Garbee

This comment has been minimized.

Copy link
Contributor

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.

Copy link
Author

commented Aug 16, 2017

Not running as root

@Garbee

This comment has been minimized.

Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link

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.

Copy link
Contributor

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.

@ddibiase

This comment has been minimized.

Copy link

commented Jan 20, 2019

I've managed to get libx11 installed on Ubuntu 18 via Docker but for some reason Puppeteer doesn't seem to be utilizing it. When I initialize my node app do I need to run it within x11 or is it sufficient to just install the live and run the node app that's depending on Puppeteer?

Also I have no-sandbox enabled. Matter of fact these are the arguments I'm passing in:

    '--no-sandbox',
    '--disable-setuid-sandbox',
    '--disable-gpu',
    `--window-size=${resolution[0]}x${resolution[1]}`,
    `--user-agent=${agent}`

Anyone have a similar issue? PS I'm running this on a microdevice (Odroid XU-4 which has no video out ability).

@Garbee

This comment has been minimized.

Copy link
Contributor

commented Jan 20, 2019

@ddibiase ARM platforms are not supported by default. You may be able to install Chromium from the repositories and point puppeteer to use that. But there is no specific guarantee still that it will run.

@ddibiase

This comment has been minimized.

Copy link

commented Jan 20, 2019

@JoshuaGhost

This comment has been minimized.

Copy link

commented Jan 21, 2019

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)

Thank you so much @bamarch i've checked my kernel setting and user namespace is enabled but is masked by the security patch you mentioned. It is also mentioned it is a permanent way of enabling the user namespace. I wonder whether there is a more "temporal" way of fixing it, which is compatible with both this patch as well as enabling the user namespace while running chrome?

@rudyhadoux

This comment has been minimized.

Copy link

commented Feb 1, 2019

Why create things so difficult to install ?????
Impossible to install within Amazon Linux AMI release 2018.03.

@wuno

This comment has been minimized.

Copy link

commented Feb 1, 2019

@rudyhadoux Did you try using a container like Docker? I posted a Docker file config above a few comments and that is working for us in production to this day.

@rudyhadoux

This comment has been minimized.

Copy link

commented Feb 1, 2019

I use AWS Amplify Console CI and it is Amazon Linux AMI release 2018.03 by default and unchangeable.
Thanks.

@rudyhadoux

This comment has been minimized.

Copy link

commented Feb 1, 2019

@wuno Furthermore I use a karma.conf.js in an Angular 7 app.

mstockerl added a commit to DigitalProductschool/website that referenced this issue Feb 7, 2019

@JnuSimba

This comment has been minimized.

Copy link

commented Feb 21, 2019

mark

@rudyhadoux

This comment has been minimized.

Copy link

commented Feb 21, 2019

It works for me. If it helps, my amplify.yml :

version: 0.1
frontend:
phases:
install:
commands:
- npm i

preBuild:
  commands:
    - curl https://intoli.com/install-google-chrome.sh | bash
    - npm i -g @angular/cli
    - npm i --save-dev @angular-devkit/build-angular
    - npm i @angular-devkit/build-angular
    - ng t
    - ng e2e

build:
  commands:
    - npm i -g @angular/cli
    - ng build --prod --build-optimizer

artifacts:
baseDirectory: dist
files:
- '**/*'

@Subair-tc

This comment has been minimized.

Copy link

commented Apr 5, 2019

apt-get install gconf-service libasound2 libatk1.0-0 libatk-bridge2.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

Please try above command for installing all dependencies.

@Garbee

This comment has been minimized.

Copy link
Contributor

commented Apr 5, 2019

The command to install deps has been posted at least half a dozen times now.

Please DO NOT post the packages to install again. They are located in the troubleshooting guide and are here plenty. If you find an error in the package list, please submit a pull request to address that issue.

@KIC

This comment has been minimized.

Copy link

commented Apr 15, 2019

this works but the console prints lots of "connect /tmp/.X11-unix/X0: No such file or directory" and other stuff.

@CoVoCre

This comment has been minimized.

Copy link

commented May 26, 2019

Am I seriously supposed to copy every one of those packages by hand ?!?!?! Is there no smarter way ?

@Garbee

This comment has been minimized.

Copy link
Contributor

commented May 26, 2019

@CoVoCre If you use the list in the troubleshooting guide (or most of them here that are a single line.) They'll all install with just copy and pasting the command. So no, you don't need to copy every single one manually to install. A simple apt-get install {pack1} {pack2} ... works just fine.

@CoVoCre

This comment has been minimized.

Copy link

commented May 26, 2019

Haha, but how do I write the list if I can't copy and paste ? That was my question ;)
In fact, I ended up using an ssh server and connecting to it from another machine just to copy and paste things more easily !

mvanduijker added a commit to reality-scheveningen/reality-website that referenced this issue Jun 6, 2019

sghoweri added a commit to bolt-design-system/bolt that referenced this issue Jun 18, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.