当前位置: 首页 > news >正文

了解Docker的多阶段构建(Multi-stage Build)

概述

你有没有发现,自己构建的 Docker 镜像动不动就几百 MB,甚至上 GB?

而别人分享的镜像,功能一样,却只有几十 MB?

问题很可能出在:你把“构建环境”也打包进了最终镜像

比如:

  • 用 Node.js 构建前端,却把 node_modulesnpm 工具留在了生产镜像
  • 用 Maven 编译 Java,却把整个 JDK 打包进去
  • 用 Python 编译依赖,却包含了 pip、编译器等构建工具

这些在运行时根本不需要的文件,白白占用了大量空间,还带来了安全风险。

解决方案就是:多阶段构建(Multi-stage Build)

什么是多阶段构建

多阶段构建允许你在一个 Dockerfile 中定义多个构建阶段,每个阶段可以基于不同的基础镜像。

你可以:

  • 第一阶段:使用“胖镜像”完成编译、打包
  • 第二阶段:使用“瘦镜像”只复制必要的产物(如可执行文件、静态文件)

最终镜像只包含运行所需的内容,不包含构建工具和中间文件。

用多阶段构建优化 Node.js 应用

场景
你有一个 React 前端项目,需要:

  1. 安装依赖(npm install
  2. 打包构建(npm run build
  3. 用 Nginx 托管静态文件

普通构建(镜像臃肿)

FROM node:18-alpine
WORKDIR /app
COPY . .
RUN npm ci && npm run build
FROM nginx:alpine
COPY --from=0 /app/build /usr/share/nginx/html
EXPOSE 80

多阶段构建(镜像精简)

# 阶段 1:构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build# 阶段 2:运行阶段
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80

效果对比

方式镜像大小是否包含 Node.js?
普通构建~300MB是(不需要)
多阶段构建~20MB

体积减少 93%

多阶段构建如何工作

  1. 第一阶段builder):

    • 使用 node:18-alpine,安装所有依赖并执行 npm run build
    • 生成 build/ 目录(静态文件)
  2. 第二阶段(运行):

    • 使用极轻的 nginx:alpine(仅 ~16MB)
    • 只复制 builder 阶段生成的 build/ 文件
    • 最终镜像不包含 Node.js、npm、源码等

关键语法:COPY --from=builder ... ,表示从名为 builder 的阶段复制文件

更多场景

  1. Java(Spring Boot)项目
# 阶段 1:编译
FROM maven:3.8-openjdk-17 AS builder
COPY pom.xml .
COPY src ./src
RUN mvn package -DskipTests# 阶段 2:运行
FROM eclipse-temurin:17-jre-alpine
COPY --from=builder /target/myapp.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

优势:最终镜像使用 JRE 而非 JDK,体积更小

  1. Golang 应用
# 阶段 1:编译
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN go build -o main .# 阶段 2:运行(使用极小的 distroless 镜像)
FROM gcr.io/distroless/static-debian11
COPY --from=builder /app/main .
CMD ["/main"]

优势:最终镜像不含 shell、包管理器,极致轻量且安全

多阶段构建的好处

优势说明
镜像体积大幅减小只包含运行时所需文件
构建更高效可复用构建阶段
安全性更高不包含编译器、shell 等攻击面
职责分离构建与运行环境解耦

最佳实践

  1. 为阶段命名:使用 AS <name>,便于引用
  2. 选择合适的运行基础镜像
    • 前端:nginx:alpine
    • Java:eclipse-temurin:17-jre-alpine
    • Go:distrolessscratch
  3. 避免在最终阶段安装不必要的包
  4. 在 CI/CD 中使用多阶段构建,确保一致性

常见问题

  1. 多阶段构建会影响构建速度吗?
    不会。虽然阶段多,但 Docker 会缓存每一层,构建速度通常更快

  2. 如何只构建某个阶段?

docker build --target builder -t myapp:build .

这在调试时非常有用。

总结

传统方式多阶段构建
一个镜像搞定所有分阶段,各司其职
镜像臃肿镜像精简
安全性低安全性高

多阶段构建是编写高质量 Dockerfile 的必备技能,尤其适合生产环境

http://www.dtcms.com/a/515344.html

相关文章:

  • [特殊字符] Berry.Live:开箱即用的.NET直播流媒体服务器
  • 网站模板的修改宝安企业网站建设
  • 网站开发软件费用2018网站流量怎么做
  • 数据结构:顺序表讲解(1)
  • 第二次作业-第二章时间服务
  • Python爬虫实战:获取香港恒生指数历史数据与趋势分析
  • 【Frida Android】基础篇11:Native层hook基础——修改原生函数的返回值
  • 什么是DNS负载均衡?提升网站稳定性与容错性的方法
  • 设计自学网站哪个好建设银行网站怎么短信转账
  • 网站如何做seo优化教程迪虎科技网站建设
  • win10底部搜索栏怎么关闭 图文详解
  • 网站备案密码是什么样的大冶建设局网站
  • python学习之进程
  • PAGE下载安装图解教程(附安装包)
  • 接口练习哈哈
  • 【原理解析】详细剖析 HAMi 在支持 NVIDIA GPU 拓扑感知调度时的具体设计与实现原理
  • Dubins曲线:最短有向路径的数学之美与工程实现
  • 解读“Time Model Statistics”中的“sql execute elapsed time”
  • 图形化设计或流程编辑软件界面组件
  • C++ char 类型深度解析:字符与字节的双重身份
  • 做网站的群html5网站正在建设中模板下载
  • 常平众展做网站长沙网上房地产官网
  • 在 Linux 中实现虚拟机管理程序级行为分析
  • Jmeter请求发送加密参数详解
  • STM32G474单片机开发入门(二十二)SHT30温湿度传感器模块实战
  • 【开题答辩实录分享】以《智能垃圾回收小程序》为例进行答辩实录分享
  • FSMC-灵活的静态存储控制器
  • 开源AI大模型AI智能名片S2B2C商城小程序在护肤品文案痛点表达中的应用与效果研究
  • 《3D端游云原生协作任务数据一致性优化实战》
  • Day8C语言前期阶段练习算法之插入排序