How to build and package Node.js Lambda code along with dependencies in Docker
Recently I was working on my wife’s personal website and needed to implement AWS Lambda@Edge that resizes and compresses the requested image before returning to the users in a way similar to Resizing Images with Amazon CloudFront & Lambda@Edge (AWS CDN Blog) but faced an issue with the Node.js sharp package that heavily relies on the OS libraries so prevents compilation of the JavaScript code in a straightforward way.
I found the approach to build the code described in the AWS blog post quite sophisticated and not really reusable across different projects, searching through the internet also didn’t provide me with convenient options, so I decided to create a GitHub template repository that has all the needed operations encapsulated in a single command:
npm run package
And this is a short post explaining how it works so anyone can use it.
It is important to understand that this approach enables the compilation of the Node.js code with any libraries and runtime dependencies needed within the Docker container without using the Docker in AWS Lambda at all. The result is a zip archive that can be easily uploaded to AWS.
Dockerfile
The BASE image is based on the official Amazon Linux image to have the most similar setup to what will be used to run the Lambda code.
First, only required OS packages installed as well as nvm to have the actual Node.js runtime version — the one, that you configured for the AWS Lambda.
Next, in the BUILD image, the dependencies are installed and the npm run build
command is executed to compile the code.
After that, the APPLICATION image installs runtime dependencies only and gets the artifact from the BUILD image (dist
directory).
Eventually, all the code in the APPLICATION image, including the node_modules
directory (containing runtime dependencies only), is packaged into the function.zip
archive.
Unfortunately, I haven’t found a working way to avoid source ~/.bashrc
before when triggering npm scripts in this Dockerfile.
npm scripts
The following npm scripts are configured to do the work:
docker:build
to build the image;docker:create
to create a temporary container without starting it;docker:copy
copies thefunction.zip
archive from the container;docker:clean
removes the temporary container;package
runs the commands above in a sequence.
GitHub template repository: https://github.com/loginov-rocks/Build-Lambda-in-Docker
That’s all Folks!
Update on December 25, 2023
Upgraded GitHub repository to use Node.js 18, AWS SDK v3, Amazon Linux 2023, and all the latest dependencies.