5
votes

I'm having an issue getting a node module to load in AWS Lambda using the Serverless Framework. One of my node packages uses native libraries so I used an EC2 to create the node_module folders and then copied them to my Serverless project. Everything works if I manually zip the project and upload to AWS Lambda but if I use serverless deploy without an artifact specified, I get an error about the module (specifically: ELF file's phentsize not the expected size regarding a .node file)

I've tried adding excludeDevDependencies: false which makes the deployment larger but still gives me the error. Currently, it only works if I zip the contents of the project folder and specify that file as the artifact to upload. Is there a different way to get a node module with native bindings to deploy with Serverless?

UPDATE: After turning off the exclusion of dev dependencies, packaging using serverless package and examining the expanded zip file serverless creates, I discovered the file sizes of the .o and .a files are different in the packaged version as compared to the original. Is this normal?

enter image description here

2
your native libraries are .so? - Amit Yadav
I don’t think the issue is with the libraries themselves but more to do with running serverless deploy as it works if I manually copy them. - arvinkx
I'm seeing this too. Testing with an image file in a node module, serverless package followed by unzipping results in an image that I can't open, whereas zipping and unzipping works fine as expected. - Josh Vickery

2 Answers

2
votes

I ran into this problem and did some digging. It turns out that v1.21.0 of serverless broke packaging of binaries.

https://forum.serverless.com/t/serverless-1-21-0-breaks-sharp-library/2606

https://github.com/serverless/serverless/issues/4182

The recommended fix is to upgrade to v1.21.1.

0
votes

Since Lambda runs on a Linux container, you should be running serverless deploy from a Linux machine.

This way, your native modules will be compiled for your target architecture which is Linux.

To check the deployment package that serverless creates, you can use sls package or sls deploy --noDeploy (for older versions), and inspect the .serverless directory that it creates. You'll see a zip file in here, extract its contents, and test the code from there.

If the contents of this zip is not what you expect (not the same as when you manually copy them), then maybe something is wrong with your file structure and/or serverless.yml.