I am attempting to utilize Puppeteer on AWS Lambda for the purpose of transforming HTML content into PDF files. I have been working with the chrome-aws-lambda library as well as the puppeteer package. However, when I execute a function through sam local invoke that includes puppeteer.launch(), it triggers an error. I would appreciate any guidance on how to properly set up Puppeteer on AWS Lambda.
CDK Stack
const pdfGenerationFunction = new lambda.NodejsFunction(this, 'PDFGeneration', {
runtime: Runtime.NODEJS_14_X,
entry: 'lambda/pdf-generation/index.ts',
timeout: Duration.seconds(10),
memorySize: 1024,
layers: [
LayerVersion.fromLayerVersionArn(this, 'chrome-layer', 'arn:aws:lambda:ap-northeast-1:764866452798:layer:chrome-aws-lambda:31')
]
});
Lambda Function Code (lambda/pdf-generation/index.ts)
const chrome = require('@sparticuz/chrome-aws-lambda');
export const handler = async () => {
try {
const browserInstance = await chrome.puppeteer.launch();
} catch (err) {
console.error(err);
}
};
I have attempted different import methods, but they all return varying errors when trying to invoke puppeteer.launch().
const chrome = require('chrome-aws-lambda'); // Error: Cannot find module '/var/task/puppeteer/lib/Browser'
const puppeteerLib = require('puppeteer'); // Error: _projectRoot is undefined. Unable to create a BrowserFetcher.
import * as puppeteer from 'puppeteer'; // Error: The argument 'filename' must be a file URL object, file URL string, or absolute path string. Received undefined
Hey DancingFox,
Running Puppeteer on AWS Lambda can be tricky. Here's a concise setup:
- Use the
chrome-aws-lambda
and @sparticuz/chrome-aws-lambda
for Chromium binaries:
- In
handler
:
const chrome = require('@sparticuz/chrome-aws-lambda');
const puppeteer = require('puppeteer-core');
export const handler = async () => {
const browser = await puppeteer.launch({
args: chrome.args,
executablePath: await chrome.executablePath,
headless: chrome.headless,
});
// Your logic here
await browser.close();
};
- Ensure the Lambda's memory and timeout are sufficient (1024MB/10s looks fine).
- Check Lambda layers are correct and up to date.
Give this setup a shot!
To successfully configure Puppeteer on AWS Lambda, follow these improved guidelines for ensuring compatibility and overcoming common errors:
- Use the Correct Puppeteer and Chromium Packages
Instead of the standard Puppeteer package, use @sparticuz/chrome-aws-lambda
for optimized Chromium binaries, and pair it with puppeteer-core
:
const chrome = require('@sparticuz/chrome-aws-lambda');
const puppeteer = require('puppeteer-core');
export const handler = async () => {
try {
const browser = await puppeteer.launch({
args: chrome.args,
executablePath: await chrome.executablePath,
headless: chrome.headless,
});
// Add PDF generation logic here
await browser.close();
} catch (error) {
console.error(‘Browser launch failed:’, error);
}
};
- Lambda Configuration
Ensure you've set sufficient memory and timeout values, as Puppeteer can be resource-intensive. Your current setup with 1024MB and 10 seconds should be a good starting base. Adjust higher if necessary based on actual function runtime.
- Validate Lambda Layers
When specifying the AWS Lambda layer, ensure you're referencing the latest compatible version. You can customize the ARN if needed for your specific AWS region's latest version.
- Import Paths and Requirements
Be mindful of where the packages are imported from. Ensure that your Lambda deployment package includes both @sparticuz/chrome-aws-lambda
and puppeteer-core
within its node_modules directory.
- Error Handling
Make sure your code gracefully handles errors during the launch process to troubleshoot issues effectively. This can help in identifying whether your errors stem from Lambda settings, the package, or environmental factors.
Adapting to these suggestions should help resolve the errors during invocation and enable smooth Puppeteer operations on AWS Lambda.