Context:
Code Snippet
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('http://whatsmyuseragent.org/');
await page.screenshot({ path: `example.png` });
await browser.close();
})();
Describe the bug
I am trying to generate a PDF using playwright and Chromium as headless browser. It's working perfectly fine in the local non-dockerized env but fails as soon as runs in a docker container. After hours of debugging I have decided to test with the example from the docs page (see above) and using official dockerfile to understand if it's an issue in my env but it turns out it does not work anywhere. As soon as it reaches this line: const browser = await chromium.launch(); it throws this error:
(node:549) UnhandledPromiseRejectionWarning: Error: Protocol error (Target.setAutoAttach): Target closed.
at /home/node_modules/playwright-core/lib/chromium/crConnection.js:130:63
at new Promise (<anonymous>)
at CRSession.send (/home/node_modules/playwright-core/lib/chromium/crConnection.js:129:16)
at CRSession.<anonymous> (/home/node_modules/playwright-core/lib/helper.js:64:31)
at Function.connect (/home/node_modules/playwright-core/lib/chromium/crBrowser.js:63:27)
at Chromium.launch (/home/node_modules/playwright-core/lib/server/chromium.js:41:53)
at async /home/script.js:4:19
I am running Docker container like this:
docker container run -it --rm --ipc=host playwright:debug-4 /bin/bash
Hey, could you try to set the following environment variable before you run your actual script? Then debug messages should be printed to the console.
DEBUG=pw:browser*
e.g.
DEBUG=pw:browser* node test.js
@mxschmitt thanks for quick response, here is what I got:
root@83472c245bb4:/home# DEBUG=pw:browser* node script.js
pw:browser <launching> /root/.cache/ms-playwright/chromium-764964/chrome-linux/chrome --disable-background-networking --enable-features=NetworkService,NetworkServiceInProcess --disable-background-timer-throttling --disable-backgrounding-occluded-windows --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-background-pages --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=TranslateUI,BlinkGenPropertyTrees,ImprovedCookieControls,SameSiteByDefaultCookies --disable-hang-monitor --disable-ipc-flooding-protection --disable-popup-blocking --disable-prompt-on-repost --disable-renderer-backgrounding --disable-sync --force-color-profile=srgb --metrics-recording-only --no-first-run --enable-automation --password-store=basic --use-mock-keychain --user-data-dir=/tmp/playwright_dev_profile-8XrLZd --remote-debugging-pipe --headless --hide-scrollbars --mute-audio --no-startup-window +0ms
pw:browser <launched> pid=1984 +6ms
pw:browser:err [0512/181050.017334:ERROR:zygote_host_impl_linux.cc(89)] Running as root without --no-sandbox is not supported. See https://crbug.com/638180. +0ms
(node:1973) UnhandledPromiseRejectionWarning: Error: Protocol error (Target.setAutoAttach): Target closed.
at /home/node_modules/playwright-core/lib/chromium/crConnection.js:130:63
at new Promise (<anonymous>)
at CRSession.send (/home/node_modules/playwright-core/lib/chromium/crConnection.js:129:16)
at CRSession.<anonymous> (/home/node_modules/playwright-core/lib/helper.js:64:31)
at Function.connect (/home/node_modules/playwright-core/lib/chromium/crBrowser.js:63:27)
at Chromium.launch (/home/node_modules/playwright-core/lib/server/chromium.js:41:53)
at async /home/script.js:4:19
(node:1973) 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(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:1973) [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.
pw:browser <process did exit 1, null> +42ms
That DEBUG env var provides much more help, thanks!
I changed to
const browser = await chromium.launch({headless: true, args: ['--no-sandbox']});
and now it works! Thank you
cc @arjun27
maybe we add an internal check for that?
if (process.getuid() === 0 && !args.include("--no-sandbox")) {
console.warn("Chromium can't run without the '--no-sandbox' arg on the root user")
}
Thanks for the investigation. The dockerfile in the repo shouldn't require --no-sandbox however, since it's already handling for that. I wonder if there's another issue here.
@m0t0r, if possible, can you share the dockerfile that you were trying out (the one tagged playwright:debug-4)?
@arjun27 sorry, I actually provided a bit wrong info. I completely forgot that I removed the steps to add pwuser user from the official dockerfile, so it was running as root hence I needed to add --no-sandbox to make it work. playwright:debug-4 is exactly same as original dockerfile but without pwuser
Most helpful comment
cc @arjun27
maybe we add an internal check for that?