In my previous post, I demonstrated how to create a PDF in Lambda using wkhtmltopdf, I am sure there are folks want to use Puppeteer over wkhtmltopdf, let’s wire things up together.
To make things easier to understand here is the full solution https://github.com/crespowang/serverless-lambda-puppeteer
This time I will still be using Serverless framework. I want to put the lambda behind API Gateway, in order to configure API Gateway to play nicely with PDF as the content-type, you will need to have the following in the serverless.yml
This will add application/pdf as Binary Media Types in API Gateway settings.
This is very important according to AWS documentation.
Content-Typeheader of the response and the
Acceptheader of the original request match an entry of the
binaryMediaTypeslist, API Gateway passes through the body. This occurs when the
Content-Typeheader and the
Acceptheader are the same; otherwise, API Gateway converts the response body to the type specified in the
As I am writing it now, Lambda runtime nodejs10.x doesn’t work with chrome-aws-lambda, you will see the error if you try to execute the function.
TypeScript + Babel + WebPack
puppeteer-core + chrome-aws-lambda
I can’t use the full version of puppeteer because the deployment package will go over AWS Lambda size limit, luckily with chrome-aws-lambda it ships an appropriate chromium binary for lambda nodejs environment. puppeteer-core is a version of Puppeteer that doesn’t download Chromium by default, so together with chrome-aws-lambda it provides a “full” puppeteer and is small enough to be deployed.
It works fine in Lambda, but if you will have an error in your local dev run.
Chromium revision is not downloaded. Run "npm install" or "yarn install"
This is because as we just talked about, puppeteer-core doesn’t download chromium and chrome-aws-lambda is only for AWS lambda, ie not for your local environment, to make it work locally we need to install the full puppeteer as devDependencies, and in the code we need to check if the request comes from serverless-offline, if yes then set the executablePath to your local Chromium.
is the local executablePath for chromium we installed with puppeteer on devDependencies.
Please note that you only need the full puppeteer and the event.isOffline thing if you care about local dev environment, it is not necessary for running in AWS.
Lastly, after adjusting the serverless.yml you can deploy to your domain.
yarn sls deploy
If you send a GET request with
Accept: application/pdf header, it should open the PDF in your browser.
In summary, puppeteer-core + chrome-aws-lambda is a good solution for running puppeteer in Lambda without using layers.