多阶段构建通过FROM AS定义多个阶段,仅复制产物到极简运行镜像中。第一阶段(如builder)用完整工具链编译,第二阶段用alpine/distroless等精简镜像,通过COPY --from=阶段名提取必要文件,并创建非root用户提升安全。
多阶段构建通过一个 Dockerfile 内定义多个独立构建阶段,只把最终需要的文件复制到运行镜像中,从而剥离编译器、源码、开发依赖等非运行时内容。
每个 FROM 指令开启一个新阶段,用 AS 给它起个名字,方便后续引用:
builder,选用带完整工具链的镜像(如 golang:1.21、node:18、maven:3.8)go build、npm run build、mvn package)alpine:3.18、distroless:nonroot),不装任何构建工具运行阶段不能访问前一阶段的文件系统,必须显式用 COPY --from=阶段名 拿出需要的内容:
COPY --from=builder /app/dist /usr/share/nginx/html(前端静态资源)COPY --from=builder /app/myapp /usr/local/bin/(Go 编译好的二进制)--from=0 引用第一个阶段WORKDIR 或 RUN mkdir -p)最终镜像体积和安全性取决于运行阶段的选择:
alpine(5MB)、debian:slim(50MB)或 distroless(20MB);完全静态二进制可用 scratch(0MB)useradd -u 1001 -m appuser),再用 USER appuser 切换构建完成后别急着推送,先检查最终镜像里有什么:
docker run --rm -it your-image sh —— 如果进不去,说明用了 distroless 或 scratch,这是正常现象docker run --rm -it your-image ls -la /app —— 确认只有二进制或 dist 目录,没有 src/、node_modules/、package.json
docker history your-image —— 查看各层大小,确认构建工具层未被保留