Avoiding Common Pifalls: Deploying Node.js Backend to AWS Lambda with Docker & Serverless on MacOS

Avoiding Common Pitfalls: Deploying Node.js Backends to AWS Lambda with Docker & Serverless on macOS Deploying a Node.js (NestJS) backend to AWS Lambda using Docker and the Serverless Framework can be a smooth experience—if you know what to watch out for. On macOS, especially with Apple Silicon, there are unique challenges that can trip up even experienced developers. Here's a practical guide to the most common pitfalls and how to avoid them, based on real-world troubleshooting. 1. Global Package Permissions: Never Use sudo with Serverless Pitfall: Installing Serverless Framework globally with sudo (sudo npm i -g serverless) can cause permission errors, making it impossible to update or remove packages later. Solution: Always install Serverless globally without sudo: npm install -g serverless Or use a Node version manager (like nvm) for even more control. 2. Base Image Confusion: Use the AWS Lambda Base Image Pitfall: Using a standard Node.js image (e.g., node:20-alpine) instead of the AWS Lambda base image leads to entrypoint errors like: Error: fork/exec /usr/local/bin/docker-entrypoint.sh: exec format error Solution: Always use the AWS Lambda base image: FROM public.ecr.aws/lambda/nodejs:20 ... CMD [ "dist/lambda.handler" ] This ensures Lambda can find and invoke your handler correctly. 3. Handler Syntax: CMD Must Match Lambda's Expectations Pitfall: Using the wrong CMD in your Dockerfile, such as CMD ["node", "dist/lambda.js"], will break Lambda's invocation process. Solution: Use the format CMD [ "." ] (e.g., CMD [ "dist/lambda.handler" ]). Make sure your built JS file exports the handler as exports.handler. 4. Architecture Mismatches: Build for linux/amd64 Pitfall: On Apple Silicon (M1/M2), Docker may build images for arm64 by default, but AWS Lambda requires amd64 (x86_64). This leads to manifest errors or runtime failures. Solution: Always build with: docker buildx build --platform linux/amd64 -t lambda-img:latest --load . Check your image manifest to ensure only amd64 is present. 5. CORS Configuration: Place It in the Right Spot Pitfall: Defining CORS under each function event in serverless.yml (as you might with REST API) will cause configuration errors with HTTP API. Solution: Place CORS configuration under provider.httpApi: provider: httpApi: cors: allowedOrigins: - "*" allowedHeaders: - "*" allowedMethods: - "*" 6. Manifest Bloat: Clean Up Before Rebuilding Pitfall: Docker image manifests may accumulate unwanted architectures (unknown, arm64) if you don't clean up before rebuilding, leading to Lambda deployment failures. Solution: Regularly prune Docker images and cache: docker system prune -af docker rmi $(docker images -q) || true 7. Debugging: Always Check CloudWatch Logs Pitfall: Many Lambda errors (handler not found, runtime errors) are only visible in CloudWatch logs. Solution: After each deployment, check CloudWatch logs for your Lambda function to quickly identify and resolve issues. Final Thoughts Deploying with Docker and Serverless on macOS is powerful, but requires attention to detail. By following these best practices and learning from common mistakes, you'll save hours of frustration and ensure your backend runs smoothly on AWS Lambda. Happy deploying!

May 9, 2025 - 07:12
 0
Avoiding Common Pifalls: Deploying Node.js Backend to AWS Lambda with Docker & Serverless on MacOS

Avoiding Common Pitfalls: Deploying Node.js Backends to AWS Lambda with Docker & Serverless on macOS

Deploying a Node.js (NestJS) backend to AWS Lambda using Docker and the Serverless Framework can be a smooth experience—if you know what to watch out for. On macOS, especially with Apple Silicon, there are unique challenges that can trip up even experienced developers. Here's a practical guide to the most common pitfalls and how to avoid them, based on real-world troubleshooting.

1. Global Package Permissions: Never Use sudo with Serverless

Pitfall: Installing Serverless Framework globally with sudo (sudo npm i -g serverless) can cause permission errors, making it impossible to update or remove packages later.

Solution:

  • Always install Serverless globally without sudo:
  npm install -g serverless
  • Or use a Node version manager (like nvm) for even more control.

2. Base Image Confusion: Use the AWS Lambda Base Image

Pitfall: Using a standard Node.js image (e.g., node:20-alpine) instead of the AWS Lambda base image leads to entrypoint errors like:

Error: fork/exec /usr/local/bin/docker-entrypoint.sh: exec format error

Solution:

  • Always use the AWS Lambda base image:
  FROM public.ecr.aws/lambda/nodejs:20
  ...
  CMD [ "dist/lambda.handler" ]
  • This ensures Lambda can find and invoke your handler correctly.

3. Handler Syntax: CMD Must Match Lambda's Expectations

Pitfall: Using the wrong CMD in your Dockerfile, such as CMD ["node", "dist/lambda.js"], will break Lambda's invocation process.

Solution:

  • Use the format CMD [ "." ] (e.g., CMD [ "dist/lambda.handler" ]).
  • Make sure your built JS file exports the handler as exports.handler.

4. Architecture Mismatches: Build for linux/amd64

Pitfall: On Apple Silicon (M1/M2), Docker may build images for arm64 by default, but AWS Lambda requires amd64 (x86_64). This leads to manifest errors or runtime failures.

Solution:

  • Always build with:
  docker buildx build --platform linux/amd64 -t lambda-img:latest --load .
  • Check your image manifest to ensure only amd64 is present.

5. CORS Configuration: Place It in the Right Spot

Pitfall: Defining CORS under each function event in serverless.yml (as you might with REST API) will cause configuration errors with HTTP API.

Solution:

  • Place CORS configuration under provider.httpApi:
  provider:
    httpApi:
      cors:
        allowedOrigins:
          - "*"
        allowedHeaders:
          - "*"
        allowedMethods:
          - "*"

6. Manifest Bloat: Clean Up Before Rebuilding

Pitfall: Docker image manifests may accumulate unwanted architectures (unknown, arm64) if you don't clean up before rebuilding, leading to Lambda deployment failures.

Solution:

  • Regularly prune Docker images and cache:
  docker system prune -af
  docker rmi $(docker images -q) || true

7. Debugging: Always Check CloudWatch Logs

Pitfall: Many Lambda errors (handler not found, runtime errors) are only visible in CloudWatch logs.

Solution:

  • After each deployment, check CloudWatch logs for your Lambda function to quickly identify and resolve issues.

Final Thoughts

Deploying with Docker and Serverless on macOS is powerful, but requires attention to detail. By following these best practices and learning from common mistakes, you'll save hours of frustration and ensure your backend runs smoothly on AWS Lambda.

Happy deploying!