Repository: RafalWilinski/serverless-puppeteer-layers Branch: master Commit: efc82b881e7a Files: 8 Total size: 4.6 KB Directory structure: gitextract___tkcq6j/ ├── .gitattributes ├── .gitignore ├── README.md ├── download-latest.sh ├── handler.js ├── layer/ │ └── .gitkeep ├── package.json └── serverless.yml ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ layer/headless_shell filter=lfs diff=lfs merge=lfs -text ================================================ FILE: .gitignore ================================================ # package directories node_modules jspm_packages # Serverless directories .serverless .DS_store chrome-aws-lambda ================================================ FILE: README.md ================================================ # Serverless Puppeteer using AWS Lambda Layers

Twitter: rafalwilinski

> Recently AWS introduced [Layers](https://aws.amazon.com/about-aws/whats-new/2018/11/aws-lambda-now-supports-custom-runtimes-and-layers/) which enables sharing common code between functions and working with large dependencies (such as headless chrome) much easier. This project example returns a screenshot of page requested via `?address=` query parameter. ![Demo](assets/demo.gif?raw=true 'Demo') ### Usage It is very important to tell NPM to skip installing chromium from `puppeteer` package. To do so, installing dependencies should be done using this command: ```sh PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1 npm install ``` or ```sh PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1 yarn ``` Without this, your function size would be more than 200MB which is way too much. After that, you can simply deploy your funciton. ```sh sls deploy curl ?address=https://google.com ``` or apply this ARN to your function directly: `arn:aws:lambda:us-east-1:085108115628:layer:chrome:6` ### Bundling latest Chromium on your own Prerequisites: - `brotli` ```sh ./download-latest.sh ``` Credits for this solution go to [San Kumar](https://github.com/san-kumar) ### Author 👤 **Rafal Wilinski** - Twitter: [@rafalwilinski](https://twitter.com/rafalwilinski) - Github: [@RafalWilinski](https://github.com/RafalWilinski) ### Show your support Give a ⭐️ if this project helped you! ================================================ FILE: download-latest.sh ================================================ #!/bin/bash set -e rm -fr chrome-aws-lambda git clone --depth=1 https://github.com/alixaxel/chrome-aws-lambda.git && \ cd chrome-aws-lambda && \ make ../layer/chrome.zip echo 'Layer created successfully!' ================================================ FILE: handler.js ================================================ 'use strict'; const chromium = require('chrome-aws-lambda'); const puppeteer = chromium.puppeteer; module.exports.index = async (event, context) => { let browser = null; try { browser = await puppeteer.launch({ defaultViewport:{width:1024,height:800}, headless: true, executablePath: await chromium.executablePath, args: chromium.args, }); const page = await browser.newPage(); await page.goto(event['queryStringParameters'].address, { waitUntil: ['domcontentloaded', 'networkidle0'], }); const image = await page.screenshot({ clip: { x: 0, y: 0, width: 1024, height: 800 }, encoding: 'base64' }); return { statusCode: 200, body: image, headers: { 'Content-Type': 'image/png', }, isBase64Encoded: true }; } catch (error) { console.error(error); return { statusCode: 500 }; } finally{ if(browser) await browser.close(); } }; ================================================ FILE: layer/.gitkeep ================================================ ================================================ FILE: package.json ================================================ { "name": "serverless-puppeteer-layers", "version": "1.0.0", "description": "Recently AWS introduced [Layers](https://aws.amazon.com/about-aws/whats-new/2018/11/aws-lambda-now-supports-custom-runtimes-and-layers/) which enables sharing common code between functions and working with large dependencies (such as headless chrome) much easier.", "main": "handler.js", "dependencies": { "serverless-apigw-binary": "0.4.4", "serverless-apigwy-binary": "0.1.0" }, "devDependencies": { "chrome-aws-lambda": "^1.20.3", "puppeteer-core": "^1.20.0" }, "scripts": { "deploy": "serverless deploy" }, "repository": { "type": "git", "url": "git+https://github.com/RafalWilinski/serverless-puppeteer-layers.git" }, "author": "Rafal Wilinski", "license": "MIT", "bugs": { "url": "https://github.com/RafalWilinski/serverless-puppeteer-layers/issues" }, "homepage": "https://github.com/RafalWilinski/serverless-puppeteer-layers#readme" } ================================================ FILE: serverless.yml ================================================ service: serverless-puppeteer-layers provider: name: aws runtime: nodejs10.x package: exclude: - layer/** - chrome-aws-lambda/** - node_modules/chrome-aws-lambda/** plugins: - serverless-apigw-binary - serverless-apigwy-binary custom: apigwBinary: types: - '*/*' functions: puppeteer-orchestrator: handler: handler.index timeout: 30 memorySize: 2048 events: - http: method: GET path: /screenshot contentHandling: CONVERT_TO_BINARY layers: - { Ref: ChromeLambdaLayer } layers: chrome: package: artifact: layer/chrome.zip