October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
Chromium

How to Run Puppeteer Inside a Google Cloud Function (Cloud Run Functions)

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

You can run Puppeteer in a Google Cloud function by deploying a Node.js function with Chromium available in its container, then launching the browser from your handler. Google now calls the product Cloud Run functions; “Google Cloud Functions” remains common in older commands and searches. The essential distinction is that Puppeteer is the control library and Chromium is the browser it controls. Google’s Cloud Run browser-automation guidance describes installing Chromium in the container and identifies Puppeteer as a high-level browser-control library.

How the pieces fit together

A function invocation runs your Node.js handler in a managed container. Your handler starts Chromium, asks Puppeteer to navigate or interact with a page, collects a result such as text, a PDF or a screenshot, and returns that result in the function response. Google describes headless Chrome use cases including scraping and data extraction, form submissions, UI testing, PDFs and screenshots.

There are two deployment concerns to solve separately:

  • Function code and entry point: the source deployment needs a Node.js dependency manifest and a function entry point that the platform can invoke.
  • Browser availability: the deployed container must contain Chromium, and your Puppeteer code must launch the browser executable that is actually present there.

Google’s source deployment flow uses buildpacks and Cloud Build to create a container image, then stores that image in Artifact Registry. That does not, by itself, establish which Chromium binary, path, launch flags, memory, timeout or concurrency setting will suit a particular project. Validate those details with the selected runtime image and Puppeteer package instead of assuming one configuration works everywhere. See Google’s function deployment documentation and build-process overview.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose a supported Node.js runtime

As listed in Google’s runtime support table on September 29, 2026, Node.js 24 (nodejs24) is available for Cloud Run functions on the google-24 and google-24-full stacks. Google lists deprecation for April 30, 2028 and decommission for October 31, 2028. Node.js 22 is listed for first-generation and Run functions on the google-22 and google-22-full stacks, with deprecation April 30, 2027 and decommission October 31, 2027. Node.js 20 is listed for first-generation and Run functions on those 22 stacks, with deprecation April 30, 2026 and decommission October 30, 2026.

For a new deployment, Node.js 24 is the newest runtime in that table at the date above. Runtime availability and lifecycle dates can change; check the official table immediately before choosing a runtime. Selecting a Node.js runtime does not settle which Chromium build or Puppeteer version is compatible with it.

Prepare the function project

The following is a small handler example for a project whose deployed container already has Chromium installed and whose executable path is supplied as CHROME_BIN. It illustrates the function-side contract, not a universally tested Cloud Run browser image. Before deployment, verify the chosen Puppeteer release supports your Chromium build and that its launch requirements work in your container.

1. Create the dependency manifest

In an empty project directory, create package.json:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
{
  "name": "puppeteer-cloud-function",
  "version": "1.0.0",
  "private": true,
  "main": "index.js",
  "engines": { "node": "24.x" },
  "scripts": { "start": "functions-framework --target=handler" },
  "dependencies": {
    "@google-cloud/functions-framework": "^3.4.0",
    "puppeteer-core": "^24.0.0"
  }
}

This manifest declares a Functions Framework server and Puppeteer’s browser-control package. The version ranges are example starting points, not a compatibility guarantee or a Google-prescribed pairing. Pin and test the versions you deploy. Because puppeteer-core does not supply a browser executable, the container build must provide Chromium and set CHROME_BIN to its real path. If you choose a package that downloads a browser, verify that the browser is actually included in the built image and is compatible with the runtime; do not assume a local install will be present after source deployment.

2. Add the handler

Create index.js:

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

exports.handler = async (req, res) => {
  const target = req.query.url;
  if (!target) {
    return res.status(400).json({ error: 'Pass a URL in the url query parameter.' });
  }

  let parsed;
  try {
    parsed = new URL(target);
  } catch {
    return res.status(400).json({ error: 'The url parameter must be a valid URL.' });
  }
  if (!['http:', 'https:'].includes(parsed.protocol)) {
    return res.status(400).json({ error: 'Only http and https URLs are supported.' });
  }

  if (!process.env.CHROME_BIN) {
    return res.status(500).json({ error: 'CHROME_BIN is not configured.' });
  }

  let browser;
  try {
    browser = await puppeteer.launch({
      executablePath: process.env.CHROME_BIN,
      headless: true,
      args: ['--no-sandbox']
    });
    const page = await browser.newPage();
    await page.setViewport({ width: 1365, height: 900 });
    await page.goto(target, { waitUntil: 'networkidle2', timeout: 30000 });
    const title = await page.title();
    const screenshot = await page.screenshot({ type: 'png' });
    res.set('Content-Type', 'application/json');
    return res.status(200).json({ title, screenshotBase64: screenshot.toString('base64') });
  } catch (error) {
    console.error('Browser capture failed:', error);
    return res.status(502).json({ error: 'The page could not be captured.' });
  } finally {
    if (browser) await browser.close();
  }
};

The example accepts a URL from the caller, visits it, and returns the page title plus a base64-encoded PNG. Base64 makes a convenient demonstration response, but it increases payload size; for a production capture workflow, consider writing the image to object storage or returning a controlled download URL. The --no-sandbox launch argument is shown as an implementation choice that often arises in containerized browser setups, not as a setting prescribed by the cited Google pages. Assess the security implications for your environment, restrict who can invoke the function, and do not expose an unrestricted URL-fetching endpoint to untrusted callers.

3. Test locally with the same browser assumptions

Install dependencies and start the function framework in an environment where Chromium is installed and CHROME_BIN points to it:

npm install
CHROME_BIN=/path/to/chromium npm start

Then invoke the local handler with a URL-encoded target, for example:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl --get 'http://localhost:8080' --data-urlencode 'url=https://example.com'

The returned JSON should include a title and the screenshot data. Replace the local Chromium path with the actual path in your deployment image; the example path is not a value to copy into production.

Deploy the function from source

Google’s documented Cloud Run functions deployment flow uses gcloud run deploy with source, function, base-image and region options. A command in that shape is:

gcloud run deploy puppeteer-capture 
  --source . 
  --function handler 
  --base-image nodejs24 
  --region REGION

Replace REGION with a region available to your project. Confirm the currently accepted base-image identifier and required deployment options in Google’s deployment instructions; the runtime table names the runtime as nodejs24 and the corresponding stack as google-24, but a runtime name and a base-image flag are not necessarily interchangeable. Most importantly, make sure the deployment actually installs Chromium and defines CHROME_BIN. If your source buildpack configuration cannot supply the browser and system dependencies you need, build and deploy a container image that includes them, following Google’s container and browser guidance.

After deployment, invoke the service URL with a properly encoded url query parameter. Restrict invocation or add your own authentication and request validation: a service that fetches caller-provided URLs can otherwise be abused to make requests to internal or sensitive addresses. URL scheme validation in the sample is only a starting check and does not prevent DNS rebinding, redirects to internal hosts or other server-side request forgery risks.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Make browser captures reliable

Wait for the result your task needs

The sample waits for networkidle2, but some pages keep analytics, streaming or polling connections open; others render their important content only after a particular element appears. Choose a wait condition based on the target task, and use a bounded timeout so one page cannot hold an invocation indefinitely. For scraping, wait for the content selector and extract the required data. For a PDF or screenshot, confirm the page has finished the visual work that matters before capturing.

Keep browser and function resources aligned

Chromium consumes more memory and startup work than a simple HTTP handler. Measure cold starts and normal requests in your own deployment, especially if each invocation launches a new browser. Close the browser in a finally block, as above, so navigation errors do not leave a process behind. Avoid sharing a live browser process across requests until you have verified the concurrency and isolation behavior you need.

The reviewed Google documentation describes the platform shape but does not publish a Puppeteer-specific memory, timeout or concurrency profile. Set these according to your tested page size, browser behavior and request duration; do not treat a copied number as universally safe. If captures are slow or large, separate the HTTP request from the browser job using an asynchronous queue or job workflow, and return a job identifier rather than keeping a client connection open.

Choose an appropriate browser-control layer

Google names Puppeteer and Playwright as high-level browser APIs and Chrome DevTools Protocol as a lower-level control option. If you already use one library, staying with it can reduce code changes; compare the browser version it needs, the container packaging work and the capabilities your task requires. Google’s cited page does not establish a universal winner or a cost benchmark among those options.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting

  • “Could not find Chrome” or executable launch failure: the container lacks Chromium, CHROME_BIN is unset, or the path is wrong. Inspect the built image and configure the path to the executable that is actually installed.
  • Browser starts locally but not after deployment: local dependencies may not be included in the source-built container. Confirm the build output contains the browser and required shared libraries; use a container image build if the source buildpack path does not provide them.
  • Browser and Puppeteer protocol errors: the browser build and Puppeteer release may not be compatible. Pin both deliberately and test the exact deployed image rather than changing launch flags at random.
  • Navigation timeouts: the target may be slow, unresponsive, or still making background requests. Use a task-appropriate wait condition, apply a finite navigation timeout, and capture a useful error in logs without returning internal stack traces to callers.
  • Empty or incomplete screenshot: the page may render content after navigation appears complete. Wait for a meaningful selector or application-ready condition and verify viewport and page state before capturing.
  • Function response is too large: an image encoded into JSON as base64 expands the response. Store larger output separately or use an image response or download flow appropriate to the service.
  • Unexpected security exposure: accepting arbitrary URLs can create server-side request risks. Authenticate callers, restrict destinations where possible, validate redirects and network egress, and avoid treating protocol checks alone as sufficient protection.

Or skip the browser setup

If the goal is simply to get a website screenshot, ScreenshotNeo provides a screenshot API and MCP server. A single GET request returns an image or PDF; the API documentation is at screenshotneo.com/docs.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp

ScreenshotNeo removes cookie/consent banners, newsletter popups and chat widgets before capture, with each step configurable. Bot checks, blank pages and failed loads are not billed, and the response identifies page verdict and billing status in headers. Its MCP server offers take_screenshot, get_page_info and capture_pdf for AI agents. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Sign up for the free plan.

Frequently asked questions

Can a Cloud Run function return a PDF instead of a screenshot?

Yes, Puppeteer can produce a PDF from a page; Google lists PDF creation among headless Chrome use cases. Configure the browser operation and HTTP response for your required document format, and validate output size and page settings for the pages you process.

Is Puppeteer the same thing as Chromium?

No. Puppeteer is the API your Node.js code uses to control the browser; Chromium is the browser process it launches. Both sides of that pairing need to be available and compatible in the deployed environment.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Does this setup work on first-generation Cloud Functions?

The current article follows Google’s Cloud Run functions source-deployment path. Google’s deployment documentation also discusses backward-compatible Cloud Functions v2 and gcloud functions workflows; check that documentation and the runtime table for the exact generation and command path you intend to use.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.