PDFPipe

Serverless functions / Azure Functions

Puppeteer on Azure Functions: a plan that installs nothing

On the Consumption plan the browser either fails to start with a missing shared library, or is blocked from spawning at all.

What is actually wrong

The Consumption plan deploys code into an environment the platform owns. There is no image to add packages to, and the sandbox restricts what a function process may spawn. Chromium needs both: system libraries that are not present, and permission to start a subprocess tree. Neither is a setting you can change on that plan.

What Azure Functions gives you to work with

a function host that runs your code inside an environment it manages, with the amount of control depending entirely on which hosting plan you chose.

  • Packaging: on the Consumption plan you deploy code, not an image, so there is no way to install a system package. Anything needing shared libraries that are not already present has no path to being there.
  • Filesystem: a temporary directory is writable and is not shared between instances. The application directory is read-only in the packaged deployment mode that Consumption uses.
  • Processes: the sandbox restricts what a function can spawn, and the restriction is tighter on Windows than on Linux. A custom container on a plan that supports one is the route that removes the restriction.

The fix, if you are keeping Puppeteer

Move to a plan that accepts a custom container, and build an image with the browser and its dependencies. This is not a workaround so much as choosing a different product: it changes the billing model from per-execution to per-instance, which is usually the reason Consumption was chosen in the first place.

What still hurts after that

Once you are running a container with a minimum instance count and paying for it whether or not documents are being rendered, the serverless economics that motivated the original design have gone. That is worth noticing before spending a week on the migration rather than after.

What Puppeteer is genuinely good at

it renders exactly what a browser renders, which means modern CSS, web fonts and client-side JavaScript all behave the way they do in a tab. That is worth keeping in view: the problem on this page is where it runs, not what it produces. Puppeteer is a Node library that drives a real Chromium, and downloads that Chromium into node_modules when it is installed. It needs the browser binary, a long list of shared libraries the browser links against, fonts, and enough memory for a browser process that is not accounted for by your runtime's heap settings.

The other shape of the answer

Every fix above keeps the renderer inside your deployment, which means the constraint stays yours: the package size, the shared libraries, the fonts, the memory, the patching. The alternative is an HTTP call from Azure Functions to something that already has a browser in it, which turns all of the above into a request and a response. That is what this API is, and it is the reason these pages exist. Whether that trade is right depends on whether rendering is a thing you want to operate.

Frequently asked

Can Puppeteer run on Azure Functions at all?

Move to a plan that accepts a custom container, and build an image with the browser and its dependencies. This is not a workaround so much as choosing a different product: it changes the billing model from per-execution to per-instance, which is usually the reason Consumption was chosen in the first place. Whether that is worth doing is a separate question from whether it is possible, and the section above on what still hurts is the honest answer to it.

Why does it work locally?

Because a development machine has root, a package manager, several gigabytes of memory, a full font set and no packaging limit. Every one of those is a thing Azure Functions constrains. A renderer that works locally and fails on deploy has not regressed: it has met the first environment that does not give it everything.

Related failures

The same platform with a different renderer, and the same renderer on other platforms.

If the render moves off this platform, none of the above is your problem to keep solving. 100 free documents a month, and a playground that needs no signup.