docker多阶段构建
本文最后更新于11 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

一、为什么要用 Docker 多阶段构建(背景)

在 Java 项目容器化过程中,常见流程是:

mvn clean package → 生成 jar → java -jar 运行

如果我们直接在一个镜像中完成构建 + 运行,会带来几个问题:

  • ❌ 镜像中包含 Maven、JDK、源码、依赖缓存
  • ❌ 镜像体积大(400MB+)
  • ❌ 构建工具暴露在运行环境中(安全风险)
  • ❌ 启动慢、攻击面大

**Docker 多阶段构建(Multi-stage Build)**就是为了解决这些问题而生的。


二、单阶段构建的问题回顾(你的 back:v1)

Dockerfile(单阶段)

FROM maven:3.9.8-eclipse-temurin-11 
WORKDIR /app COPY pom.xml ./ 
COPY src ./src RUN mvn clean package -DskipTests 
EXPOSE 5000 
CMD ["java","-jar","/app/target/app.jar"]

特点

  • Maven + JDK + jar 都在一个镜像中
  • docker images back:v1体积 ≈411MB

问题总结

问题说明
镜像臃肿Maven 镜像本身就 300MB+
不安全构建工具暴露在生产容器
不专业不符合生产环境最小化原则

三、Docker 多阶段构建的核心思想(重点)

构建和运行,分离在不同阶段

  • 第一阶段:只负责“编译”
  • 第二阶段:只负责“运行”

Docker 会:

  • 只保留最后一个阶段的内容
  • 前面阶段的 Maven / 源码 / 缓存不会进入最终镜像

四、多阶段 Dockerfile 结构解析(你的 back:v2)

多阶段 Dockerfile(标准写法)

# ---------- Stage 1:构建阶段 ---------- 
FROM maven:3.9.8-eclipse-temurin-11 AS build 
WORKDIR /app COPY pom.xml ./ 
COPY src ./src 
RUN mvn clean package -DskipTests

———- Stage 2:运行阶段 ———-

FROM eclipse-temurin:11-jre 
WORKDIR /app 
COPY --from=build /app/target/*.jar /app/app.jar 
EXPOSE 5000 
CMD ["java","-jar","/app/app.jar"]`

关键知识点逐条解释(⭐重点)

1️⃣AS build

FROM maven:... AS build

  • 给第一阶段起名:build
  • 后面可以通过--from=build 精确引用它的产物

2️⃣ 构建阶段只做一件事:产出 jar

RUN mvn clean package -DskipTests

  • Maven、源码、依赖都留在 build 阶段
  • 最终只需要target/*.jar

3️⃣ 运行阶段只复制 jar(最重要)

COPY --from=build /app/target/*.jar /app/app.jar

这行代码是多阶段构建的灵魂

  • 只把 jar 拷贝到最终镜像
  • 不带 Maven
  • 不带源码
  • 不带.m2 缓存

4️⃣ 最终镜像只保留 JRE

FROM eclipse-temurin:11-jre

  • 比 maven 镜像小很多
  • 只用于运行 Java
  • 启动更快,攻击面更小

五、构建结果对比(非常适合写进笔记)

镜像构建方式体积
back:v1单阶段(Maven + 运行)411MB
back:v2多阶段(Build → JRE)147MB

体积减少约 65%+


六、完整验证流程总结(你实际做的步骤)

1️⃣ 构建前端镜像

cd fronted docker build -t front:v1 .


2️⃣ 构建后端镜像(多阶段)

cd personal-memo docker build -t back:v2 .


3️⃣ docker-compose 组合运行

services:
  backend:
    image: back:v2
    container_name: backend
    ports:
      - "5000:5000"

  frontend:
    image: front:v1
    container_name: frontend
    ports:
      - "8080:80"
    depends_on:
      - backend

启动:

docker-compose up -d


4️⃣ 功能验证

  • 前端页面:http://<server-ip>:8080
  • 后端接口:通过 Nginx/api/* 反向代理
  • 登录、业务功能正常

5️⃣ 镜像体积验证

docker images | grep back

确认:

  • back:v2明显小于back:v1
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇