log
Swift Code Chronicles

How to Build a Docker Image for AWS Lambda

Published on January 15, 2025
Updated on May 10, 2025
20 min read
AWS

In this article, we explore how to build a Docker image that can run on AWS Lambda. By utilizing multi-stage build techniques, we aim to reduce image size and leverage caching to improve build speed.

What is Multi-Stage Build?

A multi-stage build is a feature provided by Docker that allows you to separate multiple build stages within a single Dockerfile, ultimately creating a more streamlined final image. Each stage can either start from scratch or be based on the output of the previous stage. The final stage includes only the files necessary for production.

Benefits of this approach include:

  • Reduced Image Size: Contains only the files needed for execution, excluding build tools and development dependencies.
  • Enhanced Security: Minimizes exposure of unnecessary packages in the production environment.
  • Improved Build Efficiency: Fully utilizes Docker caching to avoid reinstalling dependencies.

Dockerfile

# Build Stage
FROM public.ecr.aws/docker/library/node:22.12.0-alpine AS builder

WORKDIR /app

# Install dependencies
COPY package*.json ./
RUN npm ci

# Copy project files and build
COPY . .
RUN npm run build

###################################

# Extraction Stage
FROM public.ecr.aws/docker/library/node:22.12.0-alpine AS extractor

WORKDIR /app

# Copy only necessary files
COPY --from=builder /app/build ./build
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/package-lock.json ./package-lock.json

# Install production dependencies only
RUN npm ci --omit=dev

###################################

# Runtime Stage
FROM public.ecr.aws/docker/library/node:22.12.0-alpine

# Add Lambda Adapter
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.8.4 /lambda-adapter /opt/extensions/lambda-adapter

WORKDIR /var/task

# Copy runtime files only
COPY --from=extractor /app/node_modules ./node_modules
COPY --from=extractor /app/build ./build
COPY --from=extractor /app/package.json ./package.json

# Expose port
EXPOSE 3000

# Start application
CMD ["npm", "run", "start"]

Highlights

  1. Base Image Selection
  • The base image node:22.12.0-alpine is selected for its lightweight nature, significantly reducing image size.
  1. Build Stage
  • Separating package.json and package-lock.json from other project files optimizes Docker caching. If project code changes but dependencies remain the same, dependency reinstallation can be avoided.
  • RUN npm run build completes the application packaging process in the build stage, ensuring only the generated build folder is passed to the next stage.
  1. Extraction Stage
  • Uses --from=builder to extract build outputs and necessary runtime files.
  • Installs only production dependencies with npm ci --omit=dev, excluding development dependencies.
  1. Runtime Stage
  • Retains only the build folder, node_modules, and package.json, excluding unnecessary development and build tools.
  • Integrates AWS Lambda Adapter (/opt/extensions/lambda-adapter) to ensure compatibility with the Lambda execution environment.
  1. Final Image
  • The multi-stage build ensures that the final image contains only what is necessary for execution, greatly reducing image size.

Conclusion

The optimized Dockerfile leverages multi-stage builds, caching mechanisms, and streamlined dependency installation to significantly improve build efficiency and runtime performance. This approach is particularly suited for modern cloud-native applications that require frequent builds and deployments. Additionally, this Dockerfile is tailored for AWS Lambda environments and, with the integration of the Lambda Adapter, enables seamless application operation on Lambda.

By adopting multi-stage builds, you can minimize image size for both development and production environments, reduce potential security risks, and enhance deployment efficiency. We hope the examples and explanations in this article help you build more efficient Docker images for your projects.

About

A personal blog sharing technical insights, experiences and thoughts

Quick Links

Contact

  • Email: hushukang_blog@proton.me
  • GitHub

© 2025 Swift Code Chronicles. All rights reserved