如何构建可以在AWS Lambda里运行的Docker镜像
发布于
2025年1月15日
更新于
2025年5月10日
7
分钟阅读
AWS
在本文中,我们将探索如何构建可以在AWS Lambda里运行的Docker镜像。这里将采用多阶段构建技术来减小镜像体积并且使用缓存来提升构建速度。
什么是多阶段构建?
多阶段构建是 Docker 提供的一种构建方式,可以在同一个 Dockerfile 中分离多个构建阶段,以创建更精简的最终镜像。每个阶段可以从零开始,也可以基于前一阶段的输出,最终只将生产环境需要的文件复制到运行阶段。
这种方式的优势包括:
- 减小镜像体积:仅包含运行所需的文件,去除构建工具和开发依赖。
- 提升安全性:减少不必要的包暴露在生产环境中。
- 提高构建效率:充分利用 Docker 缓存,避免重复安装依赖。
Dockerfile
# 构建阶段
FROM public.ecr.aws/docker/library/node:22.12.0-alpine AS builder
WORKDIR /app
# 依赖安装
COPY package*.json ./
RUN npm ci
# 复制项目文件并构建
COPY . .
RUN npm run build
###################################
# 提取阶段
FROM public.ecr.aws/docker/library/node:22.12.0-alpine AS extractor
WORKDIR /app
# 仅复制必要文件
COPY --from=builder /app/build ./build
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/package-lock.json ./package-lock.json
# 安装仅生产环境需要的依赖
RUN npm ci --omit=dev
###################################
# 运行阶段
FROM public.ecr.aws/docker/library/node:22.12.0-alpine
# 添加 Lambda Adapter
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.8.4 /lambda-adapter /opt/extensions/lambda-adapter
WORKDIR /var/task
# 仅复制运行所需文件
COPY --from=extractor /app/node_modules ./node_modules
COPY --from=extractor /app/build ./build
COPY --from=extractor /app/package.json ./package.json
# 暴露端口
EXPOSE 3000
# 启动应用
CMD ["npm", "run", "start"]
亮点分析
- 基础镜像的选择
- 选择 node:22.12.0-alpine 作为基础镜像,得益于其轻量级特性,可以显著减小镜像体积。
- 构建阶段
- 将 package.json/package-lock.json 和其他项目文件分开复制是为了充分利用 Docker 缓存。如果项目代码更新而依赖未变,则可以跳过重新安装依赖的步骤。
RUN npm run build在构建阶段完成应用的打包操作,确保仅将生成的 build 文件夹传递到下一阶段。
- 提取阶段
- 通过
--from=builder提取构建输出(build 文件夹)和运行依赖。 - 使用
npm ci --omit=dev安装生产环境依赖,避免将 devDependencies 带入最终镜像。
- 运行阶段
- 仅保留 build 文件夹、node_modules 和 package.json,剥离不必要的开发和构建工具。
- 集成 AWS Lambda Adapter(/opt/extensions/lambda-adapter),确保应用兼容 Lambda 的运行环境。
- 最终镜像
- 通过多阶段构建,最终镜像仅包含运行所需的内容,大幅减小了镜像体积。
总结
优化后的 Dockerfile 利用了多阶段构建、缓存机制和精简依赖安装,极大地提升了构建效率和运行性能。这种方式特别适用于需要频繁构建和部署的现代云原生应用。并且,该 Dockerfile 专门适配 AWS Lambda 环境,结合 Lambda Adapter,可以让你的应用运行在 Lambda 中。
通过分阶段构建,你不仅可以降低开发和生产环境的镜像大小,还能减少潜在的安全风险。希望本文的示例和分析能帮助你在项目中构建更高效的 Docker 镜像!