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

Puppeteer doesn't run under WSL (Windows subsystem for Linux) #1837

Closed
jakeg opened this issue Jan 18, 2018 · 64 comments · Fixed by #9396
Closed

Puppeteer doesn't run under WSL (Windows subsystem for Linux) #1837

jakeg opened this issue Jan 18, 2018 · 64 comments · Fixed by #9396
Labels
chromium Issues with Puppeteer-Chromium confirmed documentation

Comments

@jakeg
Copy link

jakeg commented Jan 18, 2018

On Ubuntu 16.04.3 LTS via WSL (Linux pc-name 4.4.0-43-Microsoft #1-Microsoft Wed Dec 31 14:42:53 PST 2014 x86_64 x86_64 x86_64 GNU/Linux).

Gives this error:

ERROR { Error: kill ESRCH
    at Object._errnoException (util.js:1024:11)
    at process.kill (internal/process.js:183:18)
    at forceKillChrome (/mnt/c/Users/me/code/node_modules/puppeteer/lib/Launcher.js:169:19)
    at Function.launch (/mnt/c/Users/me/code/node_modules/puppeteer/lib/Launcher.js:144:7)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7) code: 'ESRCH', errno: 'ESRCH', syscall: 'kill' }
ERROR { Error: kill ESRCH
    at Object._errnoException (util.js:1024:11)
    at process.kill (internal/process.js:183:18)
    at forceKillChrome (/mnt/c/Users/me/code/node_modules/puppeteer/lib/Launcher.js:169:19)
    at Function.launch (/mnt/c/Users/me/code/node_modules/puppeteer/lib/Launcher.js:144:7)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7) code: 'ESRCH', errno: 'ESRCH', syscall: 'kill' }

Have tried:

sudo apt install 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

... which doesn't help.

Only other mention I can find of Puppeteer on WSL is #290 (comment).

@simoncpu
Copy link

I had this feeling that it won't work under WSL out of the box, so I didn't even attempt to do so. I just used VirtualBox. It would be awesome to make it run though.

@JacobDB
Copy link

JacobDB commented Mar 16, 2018

I'm seeing this as well on every WSL installation I check, here's hoping Windows 10 1803 will solve it next month.

@snooopcatt
Copy link

Would like to see pupeteer working on WSL. I am using Ubuntu in WSL and have this issue too.

@poupryc
Copy link

poupryc commented Mar 24, 2018

I'm on WSL and I have the same issue.

@mrmckeb
Copy link

mrmckeb commented Mar 26, 2018

Has anyone tried this on the newest insider builds? Something close to the upcoming Spring Creator's Update?

@JacobDB
Copy link

JacobDB commented Apr 2, 2018

Just tested in 1803, seems to work on this build (only tested on project though).

@JacobDB
Copy link

JacobDB commented Apr 3, 2018

Testing on another machine, I'm getting an "unhandled promise rejection" error. Testing some more, will report back... Using this test script I wrote.

(node:2114) UnhandledPromiseRejectionWarning: Error: kill ESRCH
    at Object._errnoException (util.js:1022:11)
    at process.kill (internal/process.js:183:18)
    at forceKillChrome (/mnt/c/Users/Jacob/Repositories/critical-test/node_modules/puppeteer/lib/Launcher.js:169:1
9)
    at Function.launch (/mnt/c/Users/Jacob/Repositories/critical-test/node_modules/puppeteer/lib/Launcher.js:144:7
)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)
(node:2114) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwin
g inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch()
. (rejection id: 1)
(node:2114) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise reje
ctions that are not handled will terminate the Node.js process with a non-zero exit code.
(node:2114) UnhandledPromiseRejectionWarning: Error: kill ESRCH
    at Object._errnoException (util.js:1022:11)
    at process.kill (internal/process.js:183:18)
    at forceKillChrome (/mnt/c/Users/Jacob/Repositories/critical-test/node_modules/puppeteer/lib/Launcher.js:169:1
9)
    at Function.launch (/mnt/c/Users/Jacob/Repositories/critical-test/node_modules/puppeteer/lib/Launcher.js:144:7
)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)
(node:2114) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwin
g inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch()
. (rejection id: 2)

@JacobDB
Copy link

JacobDB commented Apr 3, 2018

Testing on my original machine, getting the exact same error. This worked once, no clue why it wouldn't be working now. Scanning through the code where the error is occurring, it seems that the problem is something to do with the forceKillChrome() function, possibly related to how it checks what plat form it's being run on.

This is the line that's causing the error.

Things I've found while debugging:

  • console.log(process.platform) returns linux
  • console.log(typeof process.kill) returns function
  • console.log(chromeProcess.pid) returns the process number

All that seems fine to me, I can't tell what would be causing the issue.

Some Googling, it sounds like it may be an issue with the wrong pid being returned on WSL. -- see microsoft/node-pty#45

@JacobDB
Copy link

JacobDB commented Apr 3, 2018

I just installed Chromium via sudo apt-get install chromium-browser (via #1700 (comment)), and it started working with my basic test script, but still doesn't work with my gulpfile for some reason, not sure what the difference is.

@Kimeiga
Copy link

Kimeiga commented May 30, 2018

I installed Chromium via the same command and was not able to get a simple script to work; the following is the error message:

(node:761) UnhandledPromiseRejectionWarning: Error: Failed to launch chrome!


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

    at onClose (/mnt/c/Users/Kimeiga/Google Drive/Projects/web/puppeteer test/node_modules/puppeteer/lib/Launcher.js:255:14)
    at ChildProcess.helper.addEventListener (/mnt/c/Users/Kimeiga/Google Drive/Projects/web/puppeteer test/node_modules/puppeteer/lib/Launcher.js:245:60)
    at ChildProcess.emit (events.js:182:13)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:235:12)
(node:761) 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:761) [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.

The above was run through bash; I also ran it through PowerShell and received the following:


(node:6164) UnhandledPromiseRejectionWarning: AssertionError [ERR_ASSERTION]: Chromium revision is not downloaded. Run "npm install" or "yarn install"
    at Console.assert (console.js:194:23)
    at Function.launch (C:\Users\Kimeiga\Google Drive\Projects\web\puppeteer test\node_modules\puppeteer\lib\Launcher.js:100:15)
    at <anonymous>
(node:6164) 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:6164) [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.

Running npm install and yarn install didn't help

@junminstorage
Copy link

The following works for me in latest WSL:

npm install puppeteer
sudo apt-get install chromium-browser

const puppeteer = require('puppeteer');

(async() => {
  const browser = await puppeteer.launch({executablePath: '/usr/bin/chromium-browser'});
  console.log(await browser.version());
  const page = await browser.newPage();
  await page.goto('https://google.com');
  await page.screenshot({path: 'google.png'});
  await browser.close();
})();

@noinkling
Copy link

noinkling commented Aug 14, 2018

If anyone's having trouble, as an alternative option, letting it control Windows Chrome/Chromium seems to work fine (for me at least).

I added my Chrome directory to my PATH on the Windows side, it automatically gets translated/appended to PATH on the WSL side, so after that it's literally just:

const browser = await puppeteer.launch({ executablePath: 'chrome.exe' })

And this way you actually have the option of running it non-headless without having to run a window server, install a desktop environment, etc.

Obviously try and make sure you're using a compatible version.

Quick tip, if you run node --experimental-repl-await (Node 10) you can play around in a Node REPL with top level await (no need for a wrapping function), which makes testing this stuff a whole lot easier/more fun.

Edit: there is at least one caveat with this method, see below.

@jessehattabaugh
Copy link

I have added Windows Chrome to my Path, and set executablePath when I launch(). This doesn't raise an exception anymore. However, after calling newPage on the browser the script stalls and never finishes. I'm not sure if Chrome is supposed to launch, but it doesn't. I'll try to debug it and see where it's hanging. Any ideas?

@noinkling
Copy link

noinkling commented Aug 17, 2018

I was running into the same problem with newPage() in headless mode (but not with headless: false). What seems to fix it for me is setting userDataDir in the launch options. Be aware that this will be a Windows path, not a WSL one, because it gets passed to the browser as an argument. If you don't specify this, by default it tries to create a profile directory at /tmp/puppeteer_dev_profile-<randomized string>, which actually results in it being created in C:\tmp\... - maybe that causes an issue because of permissions or something.

The other issue I ran into is that this directory never gets cleaned up like it should when you close the browser, whether you manually specify userDataDir or not (you should check out C:\tmp as already mentioned because there's likely a whole bunch of useless folders in there). You can use a module like rimraf or fs-extra to remove it manually instead.

Example:

const puppeteer = require('puppeteer');
const rimraf = require('rimraf');

const USER_DATA_DIR = 'D:\\temp\\puppeteer_user_data';
const USER_DATA_DIR_WSL = '/mnt/d/temp/puppeteer_user_data';

(async () => {
  const browser = await puppeteer.launch({
    executablePath: 'chrome.exe',
    userDataDir: USER_DATA_DIR
  });

  ...

  await browser.close();
})().finally(() => rimraf(USER_DATA_DIR_WSL));

Maybe this is something that can be fixed in the library with a little WSL detection magic.

@tranxuanloc
Copy link

tranxuanloc commented Oct 11, 2018

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

@TENsaga
Copy link

TENsaga commented May 14, 2019

tranxuanloc comment allowed me to run pupeteer 1.11.0 with WSL in headless mode. The newer versions of pupeteer was causing issues for me.

@ezzatron
Copy link

ezzatron commented Jun 3, 2019

I also tried all of the solutions here. Nothing worked except disabling the sandbox unfortunately.

@blaconix
Copy link

Got it working pretty nicely on WSL2 after installing the libs, also works in headful mode through an x server (been using VcXsrv).

@dmportella
Copy link

cant wait to get wsl2 ...

@leptr
Copy link

leptr commented Jul 5, 2019

So I tried running it on wsl 2 and it just wouldn't work. Then I ran sudo apt install chromium-browser to install chromium. After that was done, in my project directory, I ran npm i puppeteer-core. After that, I included puppeteer-core in my app.js and I ran which chromium-browser to find the location of the browser itself. Once I had that, I added the path to it in the puppeteer.launch function as the executablePath argument. So my code now looks like this:

const puppeteer = require("puppeteer-core");

(async () => {
  const browser = await puppeteer.launch({
    executablePath: "/usr/bin/chromium-browser"
  });
  const page = await browser.newPage();
  await page.goto("https://www.example.com");
  await page.screenshot({ path: "example.png" });

  await browser.close();
})();

And it works flawlessly! I don't know if it works on wsl 1, I haven't tried. Someone try it and let me know.
I hope this helps you guys!

@mnpenner
Copy link

mnpenner commented Aug 20, 2019

It just hangs for me if I try setting "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe" as the executablePath unless I also add userDataDir. So, final solution to get it to run on both Windows and WSL is:

#!/usr/bin/env node
const puppeteer = require('puppeteer-core');
const rimraf = require('del');

const PATHS = {
    win32: {
        executablePath: "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe",
        userDataDir: 'C:\\Users\\<USERNAME>\\AppData\\Local\\Temp\\puppeteer_user_data',
    },
    linux: {
        executablePath: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
        userDataDir: '/mnt/c/Users/<USERNAME>/AppData/Local/Temp/puppeteer_user_data',
    },
}

async function main() {
    const browser = await puppeteer.launch({
        executablePath: PATHS[process.platform].executablePath,
        userDataDir: PATHS.win32.userDataDir,
        headless: false,
    });
    const page = await browser.newPage();
    await page.goto('https://example.org');
    await page.screenshot({path: `${__dirname}/screenshots/login.png`});

    await browser.close();
}

main().finally(async () => {
    await rimraf(PATHS[process.platform].userDataDir, {force: true})
}).catch(err => {
    console.error(err);
    process.exit(1);
});

I also couldn't get chromium-browser to work, but if you want to give it a whirl, here's some copy-pasta:

sudo add-apt-repository ppa:chromium-team/stable
sudo apt-get update
sudo apt install chromium-browser
yarn add puppeteer-core --dev
which chromium-browser

@bobdos
Copy link

bobdos commented Sep 10, 2019

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

I tried and it works...

@vielhuber
Copy link

This works for me:

const browser = await puppeteer.launch({
       args: [
            '--disable-gpu',
            '--disable-dev-shm-usage',
            '--disable-setuid-sandbox',
            '--no-first-run',
            '--no-sandbox',
            '--no-zygote',
            '--single-process',
       ]
  })

@StanleySathler
Copy link

StanleySathler commented Aug 29, 2021

It was mentioned in different ways before by a few users, but somehow got lost in the thread.

This is what worked for me on WSL2 running an Ubuntu 20.04:

  1. Install Chrome. Here's a guide.
  2. Run $ which google-chrome to check where it was installed. Probably /bin/google-chrome.
  3. Use const browser = await puppeteer.launch({ executablePath: "/bin/google-chrome" });

@bobiko
Copy link

bobiko commented Oct 22, 2021

It was mentioned in different ways before by a few users, but somehow got lost in the thread.

This is what worked for me in an Ubuntu 20.04 running WSL 2:

  1. Install Chrome. Here's a guide.
  2. Run $ which google-chrome to check where it was installed. Probably /bin/google-chrome.
  3. Use const browser = await puppeteer.launch({ executablePath: "/bin/google-chrome" });

I confirm that the above answer is the solution. It works for me.

@michallegro
Copy link

For anyone else who followed steps from #1837 (comment) - in my company we use Cisco AnyConnect VPN. This borked the network connection of WSL, so I followed this: https://gist.github.com/machuu/7663aa653828d81efbc2aaad6e3b1431
...but this step possibly (don't ask me to double-check ;)) messed up the DISPLAY var step, so here's mine:

export DISPLAY=$(route.exe print | grep -w 0.0.0.0 | tail -1 | awk '{print $4}'):0.0

basically you want this to be host ip assigned by the VPN, so double check if those are the same and if not tweak i.e. tail param

@rags2riches-prog
Copy link

I was unable to install chromium-browser through apt in the 20.20 version of Ubuntu WSL because it was "Unable to reach the snap store".

@robross0606

Likewise

@elAndyG
Copy link

elAndyG commented Dec 14, 2021

It was mentioned in different ways before by a few users, but somehow got lost in the thread.

This is what worked for me on WSL2 running an Ubuntu 20.04:

  1. Install Chrome. Here's a guide.
  2. Run $ which google-chrome to check where it was installed. Probably /bin/google-chrome.
  3. Use const browser = await puppeteer.launch({ executablePath: "/bin/google-chrome" });

I followed these steps, but only needed to use const browser = await puppeteer.launch() without specifying the executablePath.

@ceco987
Copy link

ceco987 commented Mar 18, 2022

The quickest solution for me was to install the packages listed below. After that puppeteer runs out of the box, without additional launch options for the browser.
sudo apt install libgtk-3-dev libnotify-dev libgconf-2-4 libnss3 libxss1 libasound2

@lunaperegrina
Copy link

nothing, but this works for me https://scottspence.com/2021/01/05/use-chrome-in-ubuntu-wsl/

Thank you very much! This worked for me!

@stale
Copy link

stale bot commented Jun 23, 2022

We're marking this issue as unconfirmed because it has not had recent activity and we weren't able to confirm it yet. It will be closed if no further activity occurs within the next 30 days.

@stale stale bot added the unconfirmed label Jun 23, 2022
@vuhuucuong
Copy link

vuhuucuong commented Jul 19, 2022

I'm using WSL2 and this is what worked for me!
Follow these steps from Microsoft to install Chrome on WSL.

  1. Change directories into the temp folder: cd /tmp
  2. Use wget to download it: sudo wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
  3. Get the current stable version: sudo dpkg -i google-chrome-stable_current_amd64.deb
  4. Fix the package: sudo apt install --fix-broken -y
  5. Configure the package: sudo dpkg -i google-chrome-stable_current_amd64.deb

If you are able to execute google-chrome from terminal, then your code should work

@OrKoN
Copy link
Collaborator

OrKoN commented Sep 6, 2022

We probably need to include the info into the troubleshooting guide. Happy to review a PR if someone is interested to contribute.

@Thomblin
Copy link

Thomblin commented Oct 15, 2022

I guess this is still broken. I had a similar issue that I was able to fix under puppeteer version 18.1.0 by adding chrome.exe from Windows to $PATH and adding
executablePath: 'chrome.exe', args: ['--no-sandbox', '--disable-setuid-sandbox'] to pupeteer.launch

However in the newest version, I get the error

FAIL src/App.e2e.test.js
● Test suite failed to run

Cannot find module 'puppeteer-core/internal/common/DeviceDescriptors.js' from 'node_modules/puppeteer/lib/cjs/puppeteer/puppeteer.js'

Require stack:
  node_modules/puppeteer/lib/cjs/puppeteer/puppeteer.js
  src/App.e2e.test.js

  at Resolver.resolveModule (node_modules/jest-resolve/build/resolver.js:324:11)
  at Object.<anonymous> (node_modules/puppeteer/src/puppeteer.ts:18:1)

@rationalthinker1
Copy link

I tried everything to get to work. I finally found the answer:

import chromium from "@sparticuz/chromium";

const puppeteer = require('puppeteer'); // v20.7.4 or later
(async () => {
    const browser = await puppeteer.launch({
        executablePath: await chromium.executablePath(),
        headless: chromium.headless,
        ignoreHTTPSErrors: true,
        defaultViewport: chromium.defaultViewport,
        args: [...chromium.args, "--hide-scrollbars", "--disable-web-security"],
    });
// ...
})().catch(err => {
    console.error(err);
    process.exit(1);
});

@cullen-carstens
Copy link

Does anyone know the command npx puppeteer browsers install chrome ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chromium Issues with Puppeteer-Chromium confirmed documentation
Projects
None yet
Development

Successfully merging a pull request may close this issue.