<ahref="https://www.npmjs.com/package/jest-resolve"target="_blank"rel="noopener noreferrer"><code>jest-resolve</code></a>). For the former,
we do not support deprecated versions of Node.js. For the latter, usually
upgrading the resolver (or its parent module such as <code>jest</code>) will work (e.g.
<ahref="https://github.com/puppeteer/puppeteer/issues/9121"target="_blank"rel="noopener noreferrer">https://github.com/puppeteer/puppeteer/issues/9121</a>)</p><h2class="anchor anchorWithStickyNavbar_LWe7"id="could-not-find-expected-browser-locally"><code>Could not find expected browser locally</code><aclass="hash-link"href="#could-not-find-expected-browser-locally"title="Direct link to heading"></a></h2><p>Starting from v19.0.0, Puppeteer will download browsers into
<code>~/.cache/puppeteer</code> using
<ahref="https://nodejs.org/api/os.html#oshomedir"target="_blank"rel="noopener noreferrer"><code>os.homedir</code></a> for better caching
between Puppeteer upgrades. Generally the home directory is well-defined (even
on Windows), but occasionally the home directory may not be available. In this
case, we provide the <code>PUPPETEER_CACHE_DIR</code> variable which allows you to change
the installation directory.</p><p>For example,</p><divclass="language-sh codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-sh codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token plain">PUPPETEER_CACHE_DIR=$(pwd) npm install puppeteer</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">PUPPETEER_CACHE_DIR=$(pwd) node <script-path></span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svgclass="copyButtonSuccessIcon_LjdS"viewBox="0 0 24 24"><pathd="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>You can also create a configuration file named <code>.puppeteerrc.cjs</code> (or
<code>puppeteer.config.cjs</code>) at the root of your application with the contents</p><divclass="language-js codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-js codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token keyword"style="color:#00009f">const</span><spanclass="token plain"></span><spanclass="token punctuation"style="color:#393A34">{</span><spanclass="token plain">join</span><spanclass="token punctuation"style="color:#393A34">}</span><spanclass="token plain"></span><spanclass="token operator"style="color:#393A34">=</span><spanclass="token plain"></span><spanclass="token function"style="color:#d73a49">require</span><spanclass="token punctuation"style="color:#393A34">(</span><spanclass="token string"style="color:#e3116c">'path'</span><spanclass="token punctuation"style="color:#393A34">)</span><spanclass="token punctuation"style="color:#393A34">;</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"style="display:inline-block"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token comment"style="color:#999988;font-style:italic">/**</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token comment"style="color:#999988;font-style:italic"> * @type {import("puppeteer").Configuration}</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token comment"style="color:#999988;font-style:italic"> */</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">module</span><spanclass="token punctuation"style="color:#393A34">.</span><spanclass="token property-access">exports</span><spanclass="token plain"></span><spanclass="token operator"style="color:#393A34">=</span><spanclass="token plain"></span><spanclass="token punctuation"style="color:#393A34">{</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token literal-property property"style="color:#36acaa">cacheDirectory</span><spanclass="token operator"style="color:#393A34">:</span><spanclass="token plain"></span><spanclass="token function"style="color:#d73a49">join</span><spanclass="token punctuation"style="color:#393A34">(</span><spanclass="token plain">__dirname</span><spanclass="token punctuation"style="color:#393A34">,</span><spanclass="token plain"></span><spanclass="token string"style="color:#e3116c">'.cache'</span><spanclass="token punctuation"style="color:#393A34">,</span><spanclass="token plain"></span><spanclass="token string"style="color:#e3116c">'puppeteer'</span><spanclass="token punctuation"style="color:#393A34">)</span><spanclass="token punctuation"style="color:#393A34">,</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token punctuation"style="color:#393A34">}</span><spanclass="token punctuation"style="color:#393A34">;</span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svgclass="copyButtonSuccessIcon_LjdS"viewBox="0 0 24 24"><pathd="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>You will need to reinstall <code>puppeteer</code> in order for the configuration to take
effect. See <ahref="/guides/configuring-puppeteer">Configuring
Puppeteer</a> for more information.</p><h2class="anchor anchorWithStickyNavbar_LWe7"id="chrome-headless-doesnt-launch-on-windows">Chrome headless doesn't launch on Windows<aclass="hash-link"href="#chrome-headless-doesnt-launch-on-windows"title="Direct link to heading"></a></h2><p>Some <ahref="https://support.google.com/chrome/a/answer/7532015"target="_blank"rel="noopener noreferrer">chrome policies</a> might
enforce running Chrome/Chromium with certain extensions.</p><p>Puppeteer passes <code>--disable-extensions</code> flag by default and will fail to launch
when such policies are active.</p><p>To work around this, try running without the flag:</p><divclass="language-ts codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-ts codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token keyword"style="color:#00009f">const</span><spanclass="token plain"> browser </span><spanclass="token operator"style="color:#393A34">=</span><spanclass="token plain"></span><spanclass="token keyword"style="color:#00009f">await</span><spanclass="token plain"> puppeteer</span><spanclass="token punctuation"style="color:#393A34">.</span><spanclass="token function"style="color:#d73a49">launch</span><spanclass="token punctuation"style="color:#393A34">(</span><spanclass="token punctuation"style="color:#393A34">{</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"> ignoreDefaultArgs</span><spanclass="token operator"style="color:#393A34">:</span><spanclass="token plain"></span><spanclass="token punctuation"style="color:#393A34">[</span><spanclass="token string"style="color:#e3116c">'--disable-extensions'</span><spanclass="token punctuation"style="color:#393A34">]</span><spanclass="token punctuation"style="color:#393A34">,</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token punctuation"style="color:#393A34">}</span><spanclass="token punctuation"style="color:#393A34">)</span><spanclass="token punctuation"style="color:#393A34">;</span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svgclass="copyButtonSuccessIcon_LjdS"viewBox="0 0 24 24"><pathd="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><blockquote><p>Context:
<ahref="https://github.com/puppeteer/puppeteer/issues/3681#issuecomment-447865342"target="_blank"rel="noopener noreferrer">issue 3681</a>.</p></blockquote><h2class="anchor anchorWithStickyNavbar_LWe7"id="chrome-headless-doesnt-launch-on-unix">Chrome headless doesn't launch on UNIX<aclass="hash-link"href="#chrome-headless-doesnt-launch-on-unix"title="Direct link to heading"></a></h2><p>Make sure all the necessary dependencies are installed. You can run
<code>ldd chrome | grep not</code> on a Linux machine to check which dependencies are
troubleshooting <br></li></ul></div></div></details><h2class="anchor anchorWithStickyNavbar_LWe7"id="chrome-headless-disables-gpu-compositing">Chrome headless disables GPU compositing<aclass="hash-link"href="#chrome-headless-disables-gpu-compositing"title="Direct link to heading"></a></h2><p>Chrome/Chromium requires <code>--use-gl=egl</code> to
<ahref="https://github.com/chromium/chromium/commit/19671359ae25aa1e30bde90f8ff92453eeaac2ba"target="_blank"rel="noopener noreferrer">enable GPU acceleration in headless mode</a>.</p><divclass="language-ts codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-ts codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token keyword"style="color:#00009f">const</span><spanclass="token plain"> browser </span><spanclass="token operator"style="color:#393A34">=</span><spanclass="token plain"></span><spanclass="token keyword"style="color:#00009f">await</span><spanclass="token plain"> puppeteer</span><spanclass="token punctuation"style="color:#393A34">.</span><spanclass="token function"style="color:#d73a49">launch</span><spanclass="token punctuation"style="color:#393A34">(</span><spanclass="token punctuation"style="color:#393A34">{</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"> headless</span><spanclass="token operator"style="color:#393A34">:</span><spanclass="token plain"></span><spanclass="token boolean"style="color:#36acaa">true</span><spanclass="token punctuation"style="color:#393A34">,</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"> args</span><spanclass="token operator"style="color:#393A34">:</span><spanclass="token plain"></span><spanclass="token punctuation"style="color:#393A34">[</span><spanclass="token string"style="color:#e3116c">'--use-gl=egl'</span><spanclass="token punctuation"style="color:#393A34">]</span><spanclass="token punctuation"style="color:#393A34">,</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token punctuation"style="color:#393A34">}</span><spanclass="token punctuation"style="color:#393A34">)</span><spanclass="token punctuation"style="color:#393A34">;</span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svgclass="copyButtonSuccessIcon_LjdS"viewBox="0 0 24 24"><pathd="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2class="anchor anchorWithStickyNavbar_LWe7"id="chrome-is-downloaded-but-fails-to-launch-on-nodejs-14">Chrome is downloaded but fails to launch on Node.js 14<aclass="hash-link"href="#chrome-is-downloaded-but-fails-to-launch-on-nodejs-14"title="Direct link to heading"></a></h2><p>If you get an error that looks like this when trying to launch Chromium:</p><divclass="codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-text codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token plain">(node:15505) UnhandledPromiseRejectionWarning: Error: Failed to launch the browser process!</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">spawn /Users/.../node_modules/puppeteer/.local-chromium/mac-756035/chrome-mac/Chromium.app/Contents/MacOS/Chromium ENOENT</span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,200,06,7V21A2,2
The most common cause is a bug in Node.js v14.0.0 which broke <code>extract-zip</code>, the
module Puppeteer uses to extract browser downloads into the right place. The bug
was fixed in Node.js v14.1.0, so please make sure you're running that version or
higher.</p><h2class="anchor anchorWithStickyNavbar_LWe7"id="setting-up-chrome-linux-sandbox">Setting Up Chrome Linux Sandbox<aclass="hash-link"href="#setting-up-chrome-linux-sandbox"title="Direct link to heading"></a></h2><p>In order to protect the host environment from untrusted web content, Chrome uses
<ahref="https://chromium.googlesource.com/chromium/src/+/HEAD/docs/linux/sandboxing.md"target="_blank"rel="noopener noreferrer">multiple layers of sandboxing</a>.
For this to work properly, the host should be configured first. If there's no
good sandbox for Chrome to use, it will crash with the error
<code>No usable sandbox!</code>.</p><p>If you <strong>absolutely trust</strong> the content you open in Chrome, you can launch
sandbox instead.</p></div></div><p>There are 2 ways to configure a sandbox in Chromium.</p><h3class="anchor anchorWithStickyNavbar_LWe7"id="recommended-enable-user-namespace-cloning">[recommended]<!----> Enable <ahref="http://man7.org/linux/man-pages/man7/user_namespaces.7.html"target="_blank"rel="noopener noreferrer">user namespace cloning</a><aclass="hash-link"href="#recommended-enable-user-namespace-cloning"title="Direct link to heading"></a></h3><p>User namespace cloning is only supported by modern kernels. Unprivileged user
namespaces are generally fine to enable, but in some cases they open up more
kernel attack surface for (unsandboxed) non-root processes to elevate to kernel
privileges.</p><divclass="language-bash codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token function"style="color:#d73a49">sudo</span><spanclass="token plain"> sysctl -w kernel.unprivileged_userns_clone</span><spanclass="token operator"style="color:#393A34">=</span><spanclass="token number"style="color:#36acaa">1</span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svgclass="copyButtonSuccessIcon_LjdS"viewBox="0 0 24 24"><pathd="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3class="anchor anchorWithStickyNavbar_LWe7"id="alternative-setup-setuid-sandbox">[alternative]<!----> Setup <ahref="https://chromium.googlesource.com/chromium/src/+/HEAD/docs/linux/suid_sandbox_development.md"target="_blank"rel="noopener noreferrer">setuid sandbox</a><aclass="hash-link"href="#alternative-setup-setuid-sandbox"title="Direct link to heading"></a></h3><p>The setuid sandbox comes as a standalone executable and is located next to the
Chromium that Puppeteer downloads. It is fine to re-use the same sandbox
executable for different Chromium versions, so the following could be done only
once per host environment:</p><divclass="language-bash codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token comment"style="color:#999988;font-style:italic"># cd to the downloaded instance</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token builtin class-name">cd</span><spanclass="token plain"></span><spanclass="token operator"style="color:#393A34"><</span><spanclass="token plain">project-dir-path</span><spanclass="token operator"style="color:#393A34">></span><spanclass="token plain">/node_modules/puppeteer/.local-chromium/linux-</span><spanclass="token operator"style="color:#393A34"><</span><spanclass="token plain">revision</span><spanclass="token operator"style="color:#393A34">></span><spanclass="token plain">/chrome-linux/</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token function"style="color:#d73a49">sudo</span><spanclass="token plain"></span><spanclass="token function"style="color:#d73a49">chown</span><spanclass="token plain"> root:root chrome_sandbox</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token function"style="color:#d73a49">sudo</span><spanclass="token plain"></span><spanclass="token function"style="color:#d73a49">chmod</span><spanclass="token plain"></span><spanclass="token number"style="color:#36acaa">4755</span><spanclass="token plain"> chrome_sandbox</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token comment"style="color:#999988;font-style:italic"># copy sandbox executable to a shared location</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token function"style="color:#d73a49">sudo</span><spanclass="token plain"></span><spanclass="token function"style="color:#d73a49">cp</span><spanclass="token plain"> -p chrome_sandbox /usr/local/sbin/chrome-devel-sandbox</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token comment"style="color:#999988;font-style:italic"># export CHROME_DEVEL_SANDBOX env variable</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token builtin class-name">export</span><spanclass="token plain"></span><spanclass="token assign-left variable"style="color:#36acaa">CHROME_DEVEL_SANDBOX</span><spanclass="token operator"style="color:#393A34">=</span><spanclass="token plain">/usr/local/sbin/chrome-devel-sandbox</span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svgclass="copyButtonSuccessIcon_LjdS"viewBox="0 0 24 24"><pathd="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>You might want to export the <code>CHROME_DEVEL_SANDBOX</code> env variable by default. In
this case, add the following to the <code>~/.bashrc</code> or <code>.zshenv</code>:</p><divclass="language-bash codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token builtin class-name">export</span><spanclass="token plain"></span><spanclass="token assign-left variable"style="color:#36acaa">CHROME_DEVEL_SANDBOX</span><spanclass="token operator"style="color:#393A34">=</span><spanclass="token plain">/usr/local/sbin/chrome-devel-sandbox</span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svgclass="copyButtonSuccessIcon_LjdS"viewBox="0 0 24 24"><pathd="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2class="anchor anchorWithStickyNavbar_LWe7"id="running-puppeteer-on-travis-ci">Running Puppeteer on Travis CI<aclass="hash-link"href="#running-puppeteer-on-travis-ci"title="Direct link to heading"></a></h2><blockquote><p>👋 We ran our tests for Puppeteer on Travis CI until v6.0.0 (when we've
for reference.</p></blockquote><p>Tips-n-tricks:</p><ul><li><ahref="https://en.wikipedia.org/wiki/Xvfb"target="_blank"rel="noopener noreferrer">xvfb</a> service should be launched in order
to run Chromium in non-headless mode</li><li>Runs on Xenial Linux on Travis by default</li><li>Runs <code>npm install</code> by default</li><li><code>node_modules</code> is cached by default</li></ul><p><code>.travis.yml</code> might look like this:</p><divclass="language-yml codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-yml codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token key atrule"style="color:#00a4db">language</span><spanclass="token punctuation"style="color:#393A34">:</span><spanclass="token plain"> node_js</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token key atrule"style="color:#00a4db">node_js</span><spanclass="token punctuation"style="color:#393A34">:</span><spanclass="token plain"> node</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token key atrule"style="color:#00a4db">services</span><spanclass="token punctuation"style="color:#393A34">:</span><spanclass="token plain"> xvfb</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token key atrule"style="color:#00a4db">script</span><spanclass="token punctuation"style="color:#393A34">:</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token punctuation"style="color:#393A34">-</span><spanclass="token plain"> npm test</span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svgclass="copyButtonSuccessIcon_LjdS"viewBox="0 0 24 24"><pathd="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2class="anchor anchorWithStickyNavbar_LWe7"id="running-puppeteer-on-circleci">Running Puppeteer on CircleCI<aclass="hash-link"href="#running-puppeteer-on-circleci"title="Direct link to heading"></a></h2><p>Running Puppeteer smoothly on CircleCI requires the following steps:</p><ol><li>Start with a
<ahref="https://circleci.com/docs/2.0/circleci-images/#nodejs"target="_blank"rel="noopener noreferrer">NodeJS image</a> in your
config like so:<divclass="language-yaml codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-yaml codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token key atrule"style="color:#00a4db">docker</span><spanclass="token punctuation"style="color:#393A34">:</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token punctuation"style="color:#393A34">-</span><spanclass="token plain"></span><spanclass="token key atrule"style="color:#00a4db">image</span><spanclass="token punctuation"style="color:#393A34">:</span><spanclass="token plain"> circleci/node</span><spanclass="token punctuation"style="color:#393A34">:</span><spanclass="token number"style="color:#36acaa">14</span><spanclass="token plain"></span><spanclass="token comment"style="color:#999988;font-style:italic"># Use your desired version</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token key atrule"style="color:#00a4db">environment</span><spanclass="token punctuation"style="color:#393A34">:</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token key atrule"style="color:#00a4db">NODE_ENV</span><spanclass="token punctuation"style="color:#393A34">:</span><spanclass="token plain"> development </span><spanclass="token comment"style="color:#999988;font-style:italic"># Only needed if puppeteer is in `devDependencies`</span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svgclass="copyButtonSuccessIcon_LjdS"viewBox="0 0 24 24"><pathd="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></li><li>Dependencies like <code>libXtst6</code> probably need to be installed via <code>apt-get</code>, so
entire machine (<code>36</code>) rather than the number allowed to your container (<code>2</code>).
To fix this, set <code>jest --maxWorkers=2</code> in your test command.</li></ol><h2class="anchor anchorWithStickyNavbar_LWe7"id="running-puppeteer-in-docker">Running Puppeteer in Docker<aclass="hash-link"href="#running-puppeteer-in-docker"title="Direct link to heading"></a></h2><blockquote><p>👋 We used <ahref="https://cirrus-ci.org/"target="_blank"rel="noopener noreferrer">Cirrus Ci</a> to run our tests for Puppeteer
in a Docker container until v3.0.x - see our historical
for reference. Starting from v16.0.0 we are shipping a Docker image via the
GitHub registry. The Dockerfile is located
<ahref="https://github.com/puppeteer/puppeteer/blob/main/docker/Dockerfile"target="_blank"rel="noopener noreferrer">here</a> and
the usage instructions are in the
<ahref="https://github.com/puppeteer/puppeteer#running-in-docker"target="_blank"rel="noopener noreferrer">README.md</a>. The
instructions below might be still helpful if you are building your own image.</p></blockquote><p>Getting headless Chrome up and running in Docker can be tricky. The bundled
Chromium that Puppeteer installs is missing the necessary shared library
dependencies.</p><p>To fix, you'll need to install the missing dependencies and the latest Chromium
package in your Dockerfile:</p><divclass="language-Dockerfile codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-Dockerfile codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token plain">FROM node:14-slim</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"style="display:inline-block"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># Install latest chrome dev package and fonts to support major charsets (Chinese, Japanese, Arabic, Hebrew, Thai and a few others)</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># Note: this installs the necessary libs to make the bundled version of Chromium that Puppeteer</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># installs, work.</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">RUN apt-get update \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">&& apt-get install -y wget gnupg \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">&& wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">&& sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main">> /etc/apt/sources.list.d/google.list' \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">&& apt-get update \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">&& apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"> --no-install-recommends \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">&& rm -rf /var/lib/apt/lists/*</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"style="display:inline-block"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># If running Docker >= 1.13.0 use docker run's --init arg to reap zombie processes, otherwise</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># uncomment the following lines to have `dumb-init` as PID 1</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.2/dumb-init_1.2.2_x86_64 /usr/local/bin/dumb-init</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># RUN chmod +x /usr/local/bin/dumb-init</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># ENTRYPOINT ["dumb-init", "--"]</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"style="display:inline-block"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># Uncomment to skip the chromium download when installing puppeteer. If you do,</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># you'll need to launch puppeteer with:</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># browser.launch({executablePath: 'google-chrome-stable'})</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD true</span><br></span><spanclass="token-line"style="color:#393A34"><spanclas
the command:</p><divclass="language-bash codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token function"style="color:#d73a49">docker</span><spanclass="token plain"> run -i --init --rm --cap-add</span><spanclass="token operator"style="color:#393A34">=</span><spanclass="token plain">SYS_ADMIN </span><spanclass="token punctuation"style="color:#393A34">\</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"> --name puppeteer-chrome puppeteer-chrome-linux </span><spanclass="token punctuation"style="color:#393A34">\</span><spanclass="token plain"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"></span><spanclass="token function"style="color:#d73a49">node</span><spanclass="token plain"> -e </span><spanclass="token string"style="color:#e3116c">"</span><spanclass="token string variable"style="color:#36acaa">`</span><spanclass="token string variable function"style="color:#d73a49">cat</span><spanclass="token string variable"style="color:#36acaa"> yourscript.js</span><spanclass="token string variable"style="color:#36acaa">`</span><spanclass="token string"style="color:#e3116c">"</span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svgclass="copyButtonSuccessIcon_LjdS"viewBox="0 0 24 24"><pathd="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>There's a full example at <ahref="https://github.com/ebidel/try-puppeteer"target="_blank"rel="noopener noreferrer">https://github.com/ebidel/try-puppeteer</a> that shows how
to run this Dockerfile from a webserver running on App Engine Flex (Node).</p><h3class="anchor anchorWithStickyNavbar_LWe7"id="running-on-alpine">Running on Alpine<aclass="hash-link"href="#running-on-alpine"title="Direct link to heading"></a></h3><p>The
<ahref="https://github.com/puppeteer/puppeteer/releases/tag/v13.5.0"target="_blank"rel="noopener noreferrer">Puppeteer v13.5.0</a>.</p><p>Example Dockerfile:</p><divclass="language-Dockerfile codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-Dockerfile codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token plain">FROM alpine</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"style="display:inline-block"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># Installs latest Chromium (100) package.</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">RUN apk add --no-cache \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"> chromium \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"> nss \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"> freetype \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"> harfbuzz \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"> ca-certificates \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"> ttf-freefont \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"> nodejs \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"> yarn</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"style="display:inline-block"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">...</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"style="display:inline-block"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># Tell Puppeteer to skip installing Chrome. We'll be using the installed package.</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"> PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"style="display:inline-block"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># Puppeteer v13.5.0 works with Chromium 100.</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">RUN yarn add puppeteer@13.5.0</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"style="display:inline-block"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># Add user so we don't need --no-sandbox.</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">RUN addgroup -S pptruser && adduser -S -G pptruser pptruser \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">&& mkdir -p /home/pptruser/Downloads /app \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">&& chown -R pptruser:pptruser /home/pptruser \</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain">&& chown -R pptruser:pptruser /app</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"style="display:inline-block"></span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token plain"># Run everything after as non-privileged user.</span><br></span><spanclass="token-line"style="color:#393A
different configuration to finally achieve success.</p><p>Usually the issue looks like this:</p><divclass="language-bash codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token plain">Error: Failed to launch chrome</span><spanclass="token operator"style="color:#393A34">!</span><spanclass="token plain"> spawn /usr/bin/chromium-browser ENOENT</span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svgclass="copyButtonSuccessIcon_LjdS"viewBox="0 0 24 24"><pathd="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>You need to patch two places:</p><ol><li>Your <code>gitlab-ci.yml</code> config</li><li>Arguments' list when launching pupepeteer</li></ol><p>In <code>gitlab-ci.yml</code> we need to install some packages to make it possible to
<code>'--disable-setuid-sandbox'</code> when launching Puppeteer. This can be done by
passing them as an arguments to your <code>.launch()</code> call:
<code>puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] });</code>.</p><h4class="anchor anchorWithStickyNavbar_LWe7"id="tips">Tips<aclass="hash-link"href="#tips"title="Direct link to heading"></a></h4><p>By default, Docker runs a container with a <code>/dev/shm</code> shared memory space 64MB.
This is <ahref="https://github.com/c0b/chrome-in-docker/issues/1"target="_blank"rel="noopener noreferrer">typically too small</a>
for Chrome and will cause Chrome to crash when rendering large pages. To fix,
run the container with <code>docker run --shm-size=1gb</code> to increase the size of
<code>/dev/shm</code>. Since Chrome 65, this is no longer necessary. Instead, launch the
for more details.</p><p>Seeing other weird errors when launching Chrome? Try running your container with
<code>docker run --cap-add=SYS_ADMIN</code> when developing locally. Since the Dockerfile
adds a <code>pptr</code> user as a non-privileged user, it may not have all the necessary
privileges.</p><p><ahref="https://github.com/Yelp/dumb-init"target="_blank"rel="noopener noreferrer">dumb-init</a> is worth checking out if you're
properly in some cases (e.g. in Docker).</p><h2class="anchor anchorWithStickyNavbar_LWe7"id="running-puppeteer-in-the-cloud">Running Puppeteer in the cloud<aclass="hash-link"href="#running-puppeteer-in-the-cloud"title="Direct link to heading"></a></h2><h3class="anchor anchorWithStickyNavbar_LWe7"id="running-puppeteer-on-google-app-engine">Running Puppeteer on Google App Engine<aclass="hash-link"href="#running-puppeteer-on-google-app-engine"title="Direct link to heading"></a></h3><p>The Node.js runtime of the
<ahref="https://cloud.google.com/appengine/docs/standard/nodejs/"target="_blank"rel="noopener noreferrer">App Engine standard environment</a>
comes with all system packages needed to run Headless Chrome.</p><p>To use <code>puppeteer</code>, simply list the module as a dependency in your
<code>package.json</code> and deploy to Google App Engine. Read more about using
<code>puppeteer</code> on App Engine by following
<ahref="https://cloud.google.com/appengine/docs/standard/nodejs/using-headless-chrome-with-puppeteer"target="_blank"rel="noopener noreferrer">the official tutorial</a>.</p><h3class="anchor anchorWithStickyNavbar_LWe7"id="running-puppeteer-on-google-cloud-functions">Running Puppeteer on Google Cloud Functions<aclass="hash-link"href="#running-puppeteer-on-google-cloud-functions"title="Direct link to heading"></a></h3><p>The Node.js 10 runtime of
<ahref="https://cloud.google.com/functions/docs/"target="_blank"rel="noopener noreferrer">Google Cloud Functions</a> comes with
all system packages needed to run Headless Chrome.</p><p>To use <code>puppeteer</code>, simply list the module as a dependency in your
<code>package.json</code> and deploy your function to Google Cloud Functions using the
<code>nodejs10</code> runtime.</p><h3class="anchor anchorWithStickyNavbar_LWe7"id="running-puppeteer-on-google-cloud-run">Running Puppeteer on Google Cloud Run<aclass="hash-link"href="#running-puppeteer-on-google-cloud-run"title="Direct link to heading"></a></h3><p>The default Node.js runtime of
<ahref="https://cloud.google.com/run/docs/"target="_blank"rel="noopener noreferrer">Google Cloud Run</a> does not come with the
system packages needed to run Headless Chrome. You will need to set up your own
<code>Dockerfile</code> and
<ahref="#chrome-headless-doesnt-launch-on-unix">include the missing dependencies</a>.</p><h3class="anchor anchorWithStickyNavbar_LWe7"id="running-puppeteer-on-heroku">Running Puppeteer on Heroku<aclass="hash-link"href="#running-puppeteer-on-heroku"title="Direct link to heading"></a></h3><p>Running Puppeteer on Heroku requires some additional dependencies that aren't
included on the Linux box that Heroku spins up for you. To add the dependencies
on deploy, add the Puppeteer Heroku buildpack to the list of buildpacks for your
app under Settings > Buildpacks.</p><p>The url for the buildpack is
<ahref="https://github.com/jontewks/puppeteer-heroku-buildpack"target="_blank"rel="noopener noreferrer">https://github.com/jontewks/puppeteer-heroku-buildpack</a></p><p>Ensure that you're using <code>'--no-sandbox'</code> mode when launching Puppeteer. This
can be done by passing it as an argument to your <code>.launch()</code> call:
<code>puppeteer.launch({ args: ['--no-sandbox'] });</code>.</p><p>When you click add buildpack, simply paste that url into the input, and click
save. On the next deploy, your app will also install the dependencies that
Puppeteer needs to run.</p><p>If you need to render Chinese, Japanese, or Korean characters you may need to
use a buildpack with additional font files like
<ahref="https://github.com/CoffeeAndCode/puppeteer-heroku-buildpack"target="_blank"rel="noopener noreferrer">https://github.com/CoffeeAndCode/puppeteer-heroku-buildpack</a></p><p>There's also another
<ahref="https://timleland.com/headless-chrome-on-heroku/"target="_blank"rel="noopener noreferrer">simple guide</a> from @timleland
that includes a sample project:
<ahref="https://timleland.com/headless-chrome-on-heroku/"target="_blank"rel="noopener noreferrer">https://timleland.com/headless-chrome-on-heroku/</a>.</p><h3class="anchor anchorWithStickyNavbar_LWe7"id="running-puppeteer-on-aws-lambda">Running Puppeteer on AWS Lambda<aclass="hash-link"href="#running-puppeteer-on-aws-lambda"title="Direct link to heading"></a></h3><p>AWS Lambda <ahref="https://docs.aws.amazon.com/lambda/latest/dg/limits.html"target="_blank"rel="noopener noreferrer">limits</a>
deployment package sizes to ~50MB. This presents challenges for running headless
Chrome (and therefore Puppeteer) on Lambda. The community has put together a few
resources that work around the issues:</p><ul><li><ahref="https://github.com/alixaxel/chrome-aws-lambda"target="_blank"rel="noopener noreferrer">https://github.com/alixaxel/chrome-aws-lambda</a> (kept updated with the latest
stable release of puppeteer)</li><li><ahref="https://github.com/adieuadieu/serverless-chrome/blob/HEAD/docs/chrome.md"target="_blank"rel="noopener noreferrer">https://github.com/adieuadieu/serverless-chrome/blob/HEAD/docs/chrome.md</a>
(serverless plugin - outdated)</li></ul><h3class="anchor anchorWithStickyNavbar_LWe7"id="running-puppeteer-on-aws-ec2-instance-running-amazon-linux">Running Puppeteer on AWS EC2 instance running Amazon-Linux<aclass="hash-link"href="#running-puppeteer-on-aws-ec2-instance-running-amazon-linux"title="Direct link to heading"></a></h3><p>If you are using an EC2 instance running amazon-linux in your CI/CD pipeline,
and if you want to run Puppeteer tests in amazon-linux, follow these steps.</p><ol><li><p>To install Chromium, you have to first enable <code>amazon-linux-extras</code> which
comes as part of
<ahref="https://aws.amazon.com/premiumsupport/knowledge-center/ec2-enable-epel/"target="_blank"rel="noopener noreferrer">EPEL (Extra Packages for Enterprise Linux)</a>:</p><divclass="language-sh codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-sh codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token plain">sudo amazon-linux-extras install epel -y</span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svgclass="copyButtonSuccessIcon_LjdS"viewBox="0 0 24 24"><pathd="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></li><li><p>Next, install Chromium:</p><divclass="language-sh codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-sh codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token plain">sudo yum install -y chromium</span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svgclass="copyButtonSuccessIcon_LjdS"viewBox="0 0 24 24"><pathd="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></li></ol><p>Now Puppeteer can launch Chromium to run your tests. If you do not enable EPEL
and if you continue installing chromium as part of <code>npm install</code>, Puppeteer
cannot launch Chromium due to unavailablity of <code>libatk-1.0.so.0</code> and many more
packages.</p><h2class="anchor anchorWithStickyNavbar_LWe7"id="code-transpilation-issues">Code Transpilation Issues<aclass="hash-link"href="#code-transpilation-issues"title="Direct link to heading"></a></h2><p>If you are using a JavaScript transpiler like babel or TypeScript, calling
<code>evaluate()</code> with an async function might not work. This is because while
<code>puppeteer</code> uses <code>Function.prototype.toString()</code> to serialize functions while
transpilers could be changing the output code in such a way it's incompatible
with <code>puppeteer</code>.</p><p>Some workarounds to this problem would be to instruct the transpiler not to mess
up with the code, for example, configure TypeScript to use latest ecma version
(<code>"target": "es2018"</code>). Another workaround could be using string templates
instead of functions:</p><divclass="language-ts codeBlockContainer_Ckt0 theme-code-block"style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><divclass="codeBlockContent_biex"><pretabindex="0"class="prism-code language-ts codeBlock_bY9V thin-scrollbar"><codeclass="codeBlockLines_e6Vv"><spanclass="token-line"style="color:#393A34"><spanclass="token keyword"style="color:#00009f">await</span><spanclass="token plain"> page</span><spanclass="token punctuation"style="color:#393A34">.</span><spanclass="token function"style="color:#d73a49">evaluate</span><spanclass="token punctuation"style="color:#393A34">(</span><spanclass="token template-string template-punctuation string"style="color:#e3116c">`</span><spanclass="token template-string string"style="color:#e3116c">(async() => {</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token template-string string"style="color:#e3116c"> console.log('1');</span><br></span><spanclass="token-line"style="color:#393A34"><spanclass="token template-string string"style="color:#e3116c">})()</span><spanclass="token template-string template-punctuation string"style="color:#e3116c">`</span><spanclass="token punctuation"style="color:#393A34">)</span><spanclass="token punctuation"style="color:#393A34">;</span><br></span></code></pre><divclass="buttonGroup__atx"><buttontype="button"aria-label="Copy code to clipboard"title="Copy"class="clean-btn"><spanclass="copyButtonIcons_eSgA"aria-hidden="true"><svgclass="copyButtonIcon_y97N"viewBox="0 0 24 24"><pathd="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svgclass="copyButtonSuccessIcon_LjdS"viewBox="0 0 24 24"><pathd="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></article><navclass="pagination-nav docusaurus-mt-lg"aria-label="Docs pages navigation"><aclass="pagination-nav__link pagination-nav__link--prev"href="/faq"><divclass="pagination-nav__sublabel">Previous</div><divclass="pagination-nav__label">FAQ</div></a><aclass="pagination-nav__link pagination-nav__link--next"href="/contributing"><divclass="pagination-nav__sublabel">Next</div><divclass="pagination-nav__label">Contributing</div></a></nav></div></div><divclass="col col--3"><divclass="tableOfContents_bqdL thin-scrollbar theme-doc-toc-desktop"><ulclass="table-of-contents table-of-contents__left-border"><li><ahref="#cannot-find-module-puppeteer-coreinternal"class="table-of-contents__link toc-highlight"><code>Cannot find module 'puppeteer-core/internal/...'</code></a></li><li><ahref="#could-not-find-expected-browser-locally"class="table-of-contents__link toc-highlight"><code>Could not find expected browser locally</code></a></li><li><ahref="#chrome-headless-doesnt-launch-on-windows"class="table-of-contents__link toc-highlight">Chrome headless doesn't launch on Windows</a></li><li><ahref="#chrome-headless-doesnt-launch-on-unix"class="table-of-contents__link toc-highlight">Chrome headless doesn't launch on UNIX</a></li><li><ahref="#chrome-headless-disables-gpu-compositing"class="table-of-contents__link toc-highlight">Chrome headless disables GPU compositing</a></li><li><ahref="#chrome-is-downloaded-but-fails-to-launch-on-nodejs-14"class="table-of-contents__link toc-highlight">Chrome is downloaded but fails to launch on Node.js 14</a></li><li><ahref="#setting-up-chrome-linux-sandbox"class="table-of-contents__link toc-highlight">Setting Up Chrome Linux Sandbox</a><ul><li><ahref="#recommended-enable-user-namespace-cloning"class="table-of-contents__link toc-highlight">recommended Enable user namespace cloning</a></li><li><ahref="#alternative-setup-setuid-sandbox"class="table-of-contents__link toc-highlight">alternative Setup setuid sandbox</a></li></ul></li><li><ahref="#running-puppeteer-on-travis-ci"class="table-of-contents__link toc-highlight">Running Puppeteer on Travis CI</a></li><li><ahref="#running-puppet