news 2026/8/18 18:44:58

Docker 镜像瘦身术:如何把 Spring Boot 镜像从 500MB 优化到 80MB?(多阶段构建实战)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Docker 镜像瘦身术:如何把 Spring Boot 镜像从 500MB 优化到 80MB?(多阶段构建实战)

🐘 前言:为什么你的镜像那么“胖”?

很多 Java 开发者的Dockerfile是这样写的:

# ❌ 错误示范:直接用完整的 JDK 镜像 FROM openjdk:17 COPY target/my-app.jar app.jar ENTRYPOINT ["java", "-jar", "/app.jar"]

打完包一看:580MB
为什么?因为你打包了:

  1. 完整的 JDK(javac, jdb 等开发工具,生产环境根本不需要)。
  2. 笨重的 OS(Debian/Ubuntu,包含大量无用库)。
  3. Maven 缓存(如果你在镜像里执行了 mvn package)。

今天,我们用三个步骤,把这个数字变成80MB


🔪 第一刀:换个“底座” (JRE vs JDK)

生产环境只需要运行 Java 程序,不需要编译它。
所以,请把JDK换成JRE(Java Runtime Environment)。
更进一步,把操作系统从Debian换成Alpine Linux(一个只有 5MB 大小的 Linux 发行版)。

  • OpenJDK 17 (Debian): ~400MB
  • Eclipse-Temurin 17 JRE (Alpine): ~50MB

仅仅换个 Base Image,体积就减小了 350MB!


🏗️ 第二刀:多阶段构建 (Multi-stage Builds)

这是 Docker 的杀手锏。
想象一下做饭:

  • 阶段一(厨房):锅碗瓢盆、油烟机、案板(Maven, JDK, 源码)。乱糟糟的。
  • 阶段二(餐厅):只有一盘做好的菜(Jar 包)和一副餐具(JRE)。干干净净。

我们只把“餐厅”打包给用户。

原理流程图:

阶段二: 运行环境 (Runner)
阶段一: 编译环境 (Builder)
COPY --from=builder
Alpine JRE (极简 OS)
最终镜像
Maven 构建工具
Java 源码
生成 JAR 包

🚀 终极实战:完美 Dockerfile 模板

结合多阶段构建+Alpine JRE+分层构建 (Layered Jar),这是目前 Spring Boot 的最佳实践。

新建Dockerfile

# ============================ # 阶段 1: 编译构建 (Builder) # ============================ FROM maven:3.9-eclipse-temurin-17-alpine AS builder WORKDIR /build # 1. 单独拷贝 pom.xml 利用 Docker 缓存,避免每次都重新下载依赖 COPY pom.xml . # 预下载依赖 (这一步极大加速后续构建) RUN mvn dependency:go-offline # 2. 拷贝源码并打包 COPY src ./src RUN mvn clean package -DskipTests # 3. 提取 Spring Boot 分层 (为了更好的缓存支持) # 需要在 pom.xml 开启 layers 配置,或者直接用 java -Djarmode=layertools RUN java -Djarmode=layertools -jar target/*.jar extract # ============================ # 阶段 2: 生产运行 (Runner) # ============================ FROM eclipse-temurin:17-jre-alpine WORKDIR /app # 1. 也是分层 COPY,这样如果只是改了代码,依赖层(dependencies)不需要重新传输 COPY --from=builder /build/dependencies/ ./ COPY --from=builder /build/spring-boot-loader/ ./ COPY --from=builder /build/snapshot-dependencies/ ./ COPY --from=builder /build/application/ ./ # 2. 解决 Alpine 字体缺失问题 (验证码图片可能会用到) RUN apk add --no-cache fontconfig ttf-dejavu # 3. 启动命令 (使用 JarLauncher) ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"]

📊 效果对比:瘦身成绩单

我们来对比一下三种构建方式的最终镜像大小:

xychart-beta title "Docker 镜像大小对比 (MB)" x-axis ["原始方案 (JDK+Debian)", "仅换 Base (JRE+Alpine)", "多阶段构建 (最终版)"] y-axis "镜像体积 (MB)" 0 --> 600 bar [580, 150, 85]
  • 原始方案:580MB。包含完整的 OS 和 JDK,传输慢,安全漏洞多。
  • 最终方案:85MB。极致精简,秒级拉取,攻击面极小。

📝 总结

做镜像优化不仅仅是为了“省空间”,更是为了:

  1. 更快的发布速度:80MB 的镜像推送到阿里云/AWS 仓库只需要几秒钟。
  2. 更强的安全性:Distroless 或 Alpine 去除了 curl、wget 等工具,黑客进来了也难以下载脚本。
  3. 更低的成本:云厂商的镜像仓库存储和流量都是要钱的。

记住口诀:编译用 JDK,运行用 JRE,构建分阶段,底座选 Alpine。


博主留言:
你的镜像现在有多大?有没有遇到过Alpine 里的时区不对或者DNS 解析慢的坑?

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/17 10:39:23

Meta的 Mango「芒果」模型:看来AI视频生成要变天了

📌 目录扎克伯格的「芒果」要炸场!Meta神秘AI视频模型Mango曝光:4K/60帧秒出片,好莱坞都要慌了一、Meta的野心:不止超越Sora,要把AI视频搬进专业片场(一)Mango vs 现有AI视频工具&am…

作者头像 李华
网站建设 2026/8/18 11:32:48

moodycamel::ConcurrentQueue 清空队列的方法论

方法1&#xff1a;循环弹出元素 #include <concurrentqueue.h>// 如果存储的是指针类型 moodycamel::ConcurrentQueue<int*> queue; int* item nullptr; while (queue.try_dequeue(item)) {if (item) {delete item; // 如果需要释放内存item nullptr;} }// 如果…

作者头像 李华
网站建设 2026/8/17 20:06:31

halcon窗口显示文字

前言 我们在开发C#上位机的时候&#xff0c;有时候会使用Halcon控件&#xff0c;在Halcon控件上会有绘制文字&#xff0c;本文就来介绍如何实现。 Halcon代码实现 dev_close_window () dev_open_window (0, 0, 512, 512, black, WindowHandle) set_font (WindowHandle, 宋体…

作者头像 李华
网站建设 2026/8/18 7:01:55

Langchain-Chatchat错误排查手册:常见问题与解决方案

Langchain-Chatchat 错误排查手册&#xff1a;常见问题与解决方案 在企业级 AI 应用日益强调数据隐私和本地化部署的今天&#xff0c;基于大型语言模型&#xff08;LLM&#xff09;的知识库系统正从“云端调用”转向“私有可控”。Langchain-Chatchat 作为一款开源、可离线运行…

作者头像 李华
网站建设 2026/8/17 18:14:46

AtCoder Beginner Contest竞赛题解 | 洛谷 AT_abc436_b Magic Square

​欢迎大家订阅我的专栏&#xff1a;算法题解&#xff1a;C与Python实现&#xff01; 本专栏旨在帮助大家从基础到进阶 &#xff0c;逐步提升编程能力&#xff0c;助力信息学竞赛备战&#xff01; 专栏特色 1.经典算法练习&#xff1a;根据信息学竞赛大纲&#xff0c;精心挑选…

作者头像 李华