3

I'm developing a Serverless Framework application that is using the Node runtime and is deployed to AWS. One of my AWS Lambda functions uses the sharp library.

When I run the AWS Lambda function, the following error occurs:

'darwin-x64' binaries cannot be used on the 'linux-x64' platform. Please remove the 'node_modules/sharp/vendor' directory and run 'npm install'.

I believe this error is occurring because when I run the sls deploy command on my local computer, the application is packaged on macOS and then moved to AWS. I think the application needs to be packaged on an operating system using linux-x64.

How can I deploy my Serverless Framework from my computer and still be able to use the sharp library?

groffcole
  • 871
  • 1
  • 7
  • 18

4 Answers4

4

You can install the Linux compatible package using the following:

rm -rf node_modules/sharp
npm install --arch=x64 --platform=linux --target=10.15.0 sharp

Note that this also specifies a target NodeJS version, ensure its the same version of node you're using in your Lambda. This is straight out of the docs (see here.)

However that didn't solve my problems. My serverless configuration (using serverless-bundle plugin) meant that my modules were being installed again in a separate folder, wiping out the platform-specific modules I just manually installed.

Two choices here:

  1. use serverless-plugin-scripts to hook into the deploy events to run the above patch; or
  2. run serverless in docker using a Linux container with a matching node version.

For my specific edge case I had to go with Docker. The build scripts will effect every function you're deploying -- adding ~30mb of Sharp code -- and Lambda@Edge has limitations on source code size.

noetix
  • 4,773
  • 3
  • 26
  • 47
  • This helped me - installing the sharp package with a specific `arch` defined. I read this in the official documentation, but I didn't quite understand at first. I thought that the `sls deploy` command was installing and packaging everything for me. Thank you. – groffcole Feb 03 '20 at 00:38
0

The description of https://www.npmjs.com/package/sharp suggests it is linux compatible.

I am unfamiliar with how to (or if you can) force nodes native package resolution to a separate OS. Try building your lambda zip inside a docker image https://hub.docker.com/_/alpine/

Keynan
  • 1,338
  • 1
  • 10
  • 18
  • I'm not super familiar - Is it possible to setup a Docker container to start up, build and deploy the code, and then shut down immediately? – groffcole Feb 02 '20 at 01:00
  • Yes. You mount the local file system and it does all the build things and dies as would any other process. Docker / Containers are just process isolation on steroids there's no magic here. You will probably end up with the output file being owned by root though. so you'll need to deal with that somehow. The simplest solution is probably to do the upload inside docker as well, such that you don't need to mount the file system. – Keynan Feb 02 '20 at 23:38
0

If you have not already, I would suggest following the Installing the AWS SAM CLI on macOS guide to insure you have the correct local environment for developing Serverless on macOS.

This process is designed for the macOS, and includes built-in support for Docker, so that you can build and deploy packages that are compatible with Lambda directly from your local computer.

Rodrigo Murillo
  • 13,080
  • 2
  • 29
  • 50
0

For AWS lambda deployment with Sharp module, the following worked for me when using serverless, esbuild and serverless-esbuild. Changed the serverless.yml file with the below configuration. It is basically telling esbuild to download sharp again with the following --arch=x64 --platform=linux considering your lambda uses x64 arch. Check serverless-esbuild packager and packagerOptions options for more understanding.

esbuild:
    # keep existing configurations
    external:
      - sharp
    packagerOptions:
      scripts:
        - npm install --arch=x64 --platform=linux sharp
  • I was having difficulties configuring this with webpack; This solution with esbuild works fine and without that much configuration, thanks! I had to use `npm rebuild` and `--libc=glibc` though ``` esbuild: external: - sharp packagerOptions: scripts: - npm rebuild --arch=x64 --platform=linux --libc=glibc sharp ``` – Chris Jul 14 '23 at 17:44