AWS Lambda supports container images so I tried Puppeteer

happy New Year.

AWS Lambda now supports container images, so I created a Lambda to capture with Puppeteer.

According to the following article by Class Method, the local execution worked, but when I deployed it to Lambda, it didn't work. (Error at Chrome startup timing?)

I tried using Puppeteer with a Lambda container image | Developers.IO https://dev.classmethod.jp/articles/try-using-puppeteer-with-a-lambda-container-image/

The result of trial and error is here.

Source

The whole has been uploaded here. https://github.com/moritalous/m5core2-yweather/tree/master/lambda

Dockerfile

Class Method was a combination of Google Chrome and puppeteer-core, but I wanted to run puppeteer alone, so I changed the package to install. For the package to be installed, I referred to here. Also install the Japanese font google-noto-sans-japanese-fonts.

FROM amazon/aws-lambda-nodejs:12
RUN yum -y install libX11 libXcomposite libXcursor libXdamage libXext libXi libXtst cups-libs libXScrnSaver libXrandr alsa-lib pango atk at-spi2-atk gtk3 google-noto-sans-japanese-fonts
COPY app.js package*.json ./
RUN npm install
CMD [ "app.lambdaHandler" ]

Source code

Dependent libraries are puppeteer and sharp. sharp was added to resize the screenshot taken.

package.json


  "dependencies": {
    "puppeteer": "^5.5.0",
    "sharp": "^0.27.0"
  }

About args specified in puppeteer.launch For local execution, just specifying --no-sandbox and --disable-setuid-sandbox worked fine, but on Lambda I got an error. Isn't it because the area other than the/tmp directory is read-only?

As a result of trial and error, it looks like this.

app.js


const browser = await puppeteer.launch({
    headless: true,
    args: [
        '--no-sandbox',
        '--disable-setuid-sandbox',
        '-–disable-dev-shm-usage',
        '--disable-gpu',
        '--no-first-run',
        '--no-zygote',
        '--single-process',
    ]
});

I took a capture and resized it to PNG. Since it was returned via API Gateway, Base64 encode it and set it in the response.

app.js


buff = await page.screenshot({
    clip: rect
});

buff = await sharp(buff).resize(320, 240).png().toBuffer();

base64 = buff.toString('base64');

await browser.close();

const response = {
    statusCode: 200,
    headers: {
        'Content-Length': Buffer.byteLength(base64),
        'Content-Type': 'image/png',
        'Content-disposition': 'attachment;filename=weather.png'
    },
    isBase64Encoded: true,
    body: base64
};

Push to ECR

Lambda's container image support,

It seems that.

First I couldn't try it on GitHub Container Registry, then I couldn't try it on ECR public. ..

$ aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin [AWS account ID].dkr.ecr.ap-northeast-1.amazonaws.com
$ docker build -t [AWS account ID].dkr.ecr.ap-northeast-1.amazonaws.com/[Repository name]:latest .
$ docker push [AWS account ID].dkr.ecr.ap-northeast-1.amazonaws.com/[Repository name]:latest

Creating Lambda

Basically just follow the wizard.

image.png

One thing to note is that every time you push a new image to your ECR, you need to respecify the image to use with Lambda. It seems that you are looking at the value of the sha256 digest, and you have to specify it every time even if it is the latest tag.

Creating an API Gateway

Add a trigger on the Lambda screen. It's simple. With the REST API, I think there were various steps such as enabling binary support in the past, but I was able to return the PNG image without doing anything.

image.png

Complete

I tried to make the weather of Yahoo into a PNG image.

weather.png

Recommended Posts

AWS Lambda supports container images so I tried Puppeteer
I tried running a Docker container on AWS IoT Greengrass 2.0
AWS Lambda says Container Image Support, so pseudo Cloud Run
I tried deploying a Docker container on Lambda with Serverless Framework
I tried using Pari gp container
AWS SAM CLI now supports local emulation of HttpApi, so I tried using it on WSL2 Docker
I tried to visualize the access of Lambda → Athena with AWS X-Ray
I tried to summarize Java lambda expressions
Java9 was included, so I tried jshell.
How to deploy a container on AWS Lambda
I tried running Ansible on a Docker container
First AWS Lambda (I tried to see what kind of environment it works in)