playwright-aws-lambda icon indicating copy to clipboard operation
playwright-aws-lambda copied to clipboard

Lambda deployed with CDK - ENOENT: no such file or directory, open '/var/task/bin/chromium.br

Open phstc opened this issue 2 years ago • 7 comments

I'm deploying a NodejsFunction, and I'm getting this error invoking my lambda:

ENOENT: no such file or directory, open '/var/task/bin/chromium.br

image

NodejsFunction uses esbuild that compresses the lambda code. Therefore, missing chromium binaries.

Is anyone doing something similar with a NodejsFunction that could share some snippets?

phstc avatar Feb 05 '23 16:02 phstc

Yes I feel like a step is missing here

revmischa avatar Mar 09 '23 01:03 revmischa

@revmischa now it's working for me, but I don't remember exactly what unlocked me, I forgot to update back this issue once it started to work.

What I have now:

Lambda layer contents:

npm install --prefix layer/nodejs -s chrome-aws-lambda playwright-core playwright-aws-lambda 

CDK:

const layer = new lambda.LayerVersion(this, "ChromeLayer", {
  // run npm install --prefix layer/nodejs -s chrome-aws-lambda playwright-core playwright-aws-lambda 
  code: lambda.Code.fromAsset("./layer"),
});

new NodejsFunction(scope, id, {
  runtime: lambda.Runtime.NODEJS_16_X,
  memorySize: 1024,
  bundling: {
    externalModules: [
      "chrome-aws-lambda",
      "playwright-core",
      "playwright-aws-lambda",
    ],
  },
  layers: [layer],
  timeout: Duration.minutes(15),
});

then on a lambda:

const playwright = require('playwright-aws-lambda');

// ...

const browser = await playwright.launchChromium({ headless: true });

phstc avatar Mar 09 '23 02:03 phstc

This is what I did for bundling settings in Serverless Stack:

 hooks: {
          beforeBuild: async (props, outDir) => {
            // create bin folder
            const binDir = path.join(outDir, "bin")
            if (!fs.existsSync(binDir)) fs.mkdirSync(binDir, { recursive: true })
          },
        },
        copyFiles: [
          {
            from: "backend/node_modules/playwright-aws-lambda/dist/src/bin/aws.tar.br",
            to: "./bin/aws.tar.br",
          },
          {
            from: "backend/node_modules/playwright-aws-lambda/dist/src/bin/chromium.br",
            to: "./bin/chromium.br",
          },
          {
            from: "backend/node_modules/playwright-aws-lambda/dist/src/bin/swiftshader.tar.br",
            to: "./bin/swiftshader.tar.br",
          },
        ],

but it's quite hacky

revmischa avatar Mar 09 '23 03:03 revmischa

Hello @phstc @revmischa, I am facing the "almost" same issue here: ENOENT: no such file or directory, open '/var/task/packages/functions/src/bin/[chromium.br](http://chromium.br/)' I am using SST with playwright-aws-lambda, it is working perfectly locally (with the sst dev command), but having this issue when deployed to prod: image Any idea on what could be happening?

clementmarcilhacy avatar Nov 16 '23 22:11 clementmarcilhacy

@clementmarcilhacy try marking the chromium dep as external in your sst function config, eg.:

const chromiumLayer = new lambda.LayerVersion(stack, "chromiumLayers", {
    code: lambda.Code.fromAsset("layers/chromium"),
  });

const api = new Api(stack, "api", {
    routes: {
      "GET /": {
        function: {
          handler: "packages/functions/src/lambda.handler",
          runtime: "nodejs18.x",
          timeout: 60,
          memorySize: 2048,
          layers: [chromiumLayer],
          nodejs: {
            esbuild: {
              external: ["@sparticuz/chromium"],
            },
          },
        },
      },
    },
  });

markgibaud-novata avatar Jan 13 '24 22:01 markgibaud-novata

@revmischa now it's working for me, but I don't remember exactly what unlocked me, I forgot to update back this issue once it started to work.

What I have now:

Lambda layer contents:

npm install --prefix layer/nodejs -s chrome-aws-lambda playwright-core playwright-aws-lambda 

CDK:

const layer = new lambda.LayerVersion(this, "ChromeLayer", {
  // run npm install --prefix layer/nodejs -s chrome-aws-lambda playwright-core playwright-aws-lambda 
  code: lambda.Code.fromAsset("./layer"),
});

new NodejsFunction(scope, id, {
  runtime: lambda.Runtime.NODEJS_16_X,
  memorySize: 1024,
  bundling: {
    externalModules: [
      "chrome-aws-lambda",
      "playwright-core",
      "playwright-aws-lambda",
    ],
  },
  layers: [layer],
  timeout: Duration.minutes(15),
});

then on a lambda:

const playwright = require('playwright-aws-lambda');

// ...

const browser = await playwright.launchChromium({ headless: true });

Hey I am having a similar issue. Error: ENOENT: no such file or directory, mkdtemp 'undefined\temp\playwright-artifacts-XXXXXXXXXXXX'

I have tried to follow your steps to install the dependencies on the layer. Now I have a new folder for the layer but I can't connect with the current function folder.

Also, where do you specify the CDK code? I tried adding it to MyStack.ts but I'm missing the lambda import

Am4teur avatar May 18 '24 17:05 Am4teur