Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
phstc opened this issue Feb 5, 2023 · 6 comments

Comments

@phstc
Copy link

phstc commented Feb 5, 2023

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?

@revmischa
Copy link

Yes I feel like a step is missing here

@phstc
Copy link
Author

phstc commented Mar 9, 2023

@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 });

@revmischa
Copy link

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

@clementmarcilhacy
Copy link

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?

@markgibaud-novata
Copy link

@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"],
            },
          },
        },
      },
    },
  });

@Am4teur
Copy link

Am4teur commented May 18, 2024

@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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants