OpenJDK怎么用多阶段构建减少镜像体积

酷枫小哥_8213

酷枫小哥_8213

2026-10-16

672人浏览

原创

用多阶段构建可将openjdk应用镜像从500mb+压缩至约120mb,关键在于builder阶段仅用于编译且不进入最终镜像,runner阶段必须使用纯jre镜像(如eclipse-temurin:17-jre-alpine)并精确copy jar文件。

openjdk怎么用多阶段构建减少镜像体积

直接结论:用多阶段构建能把 OpenJDK 应用镜像从 500MB+ 压到 120MB 左右,关键不是“用了多阶段”,而是 builder 阶段不带 JDK 运行时、runner 阶段不用完整 JDK 镜像。

builder 阶段必须用 maven/gradle 完整镜像,但不能进最终镜像

OpenJDK 应用(如 Spring Boot)需要编译、打包,builder 阶段得有 JDK 和构建工具。常见错误是直接用 maven:3.9-openjdk-17 打包完就 COPY target/*.jar —— 这没问题,但很多人忘了:这个镜像本身含完整 JDK,体积超 400MB,如果误把它当 runner 阶段用,就白干了。

  • builder 阶段必须显式命名:FROM maven:3.9-openjdk-17 AS builder,否则 COPY --from=builder 会报错
  • 优先用 mvn package -DskipTests 而非 mvn clean package,避免重复清理导致缓存失效
  • 如果项目用 Gradle,改用 gradle:8.5-jdk17,同样加 AS builder;别用 openjdk:17-jdk-slim 自己装 Gradle,徒增层数和体积

runner 阶段禁用 openjdk:xx-jdk 和 openjdk:xx-slim

这两个标签名里带 jdk 或没明确写 jre 的镜像,都含 javac、javadoc、jdb 等运行时完全不需要的二进制,光这部分就占 100MB+。真正该用的是只含 JRE 的精简镜像。

  • 首选 eclipse-temurin:17-jre-alpine(约 80MB)或 amazoncorretto:17-jre-alpine(约 95MB),它们不含 shell,攻击面小
  • 慎用 scratch:Java 应用依赖 glibc 和 ca-certificates,直接跑会报 No such file or directory;若硬要用,得自己 COPY 这些文件,维护成本高
  • 别信 “alpine 就一定小”:某些 alpine 镜像因 musl libc 兼容问题被迫回退到 debian-slim,体积反而更大;验证方式很简单:docker run --rm -it eclipse-temurin:17-jre-alpine java -version

COPY 产物必须精确到文件,且 runner 阶段不装任何额外工具

多阶段构建后体积反弹,90% 出在这一层:COPY 路径太宽、RUN 指令又悄悄装东西。

  • 只 COPY jar 文件:COPY --from=builder /app/target/app.jar .,别写 /app/target/ 整个目录,里面可能有 original-app.jar、classes/ 等冗余内容
  • runner 阶段禁止出现 RUN apt-get install 或 RUN apk add —— 除非真需要 ca-certificates(alpine 镜像需显式装)或 tzdata(时区需求),其他一律免谈
  • Spring Boot 2.7+ 用户注意:javax.* 包已移除,若用老版 openjdk:17-jre 可能报 NoClassDefFoundError,换 eclipse-temurin:17-jre-focal(基于 Ubuntu)更稳

验证是否真的瘦身成功,别只看 docker images

docker images 显示的 SIZE 是压缩后大小,看不出镜像里塞了什么。真正要查的是分层结构和内容构成。

  • 运行 docker history your-image-name:最终镜像应只有 2–3 层(基础镜像层 + COPY jar 层 + CMD 层),每层体积不超过几 MB;若看到几百 MB 的 RUN 层,说明 builder 阶段残留没清干净
  • 用 dive your-image-name(需提前安装)逐层查看文件分布,重点检查 /usr/lib/jvm/ 下有没有 bin/javac、lib/tools.jar 等 JDK 工具链文件
  • 启动容器后执行 ls -la /usr/lib/jvm/:JRE 镜像里应该只有 jre/ 子目录,没有 jdk/ 或顶层 bin/javac

最常被忽略的一点:多阶段构建本身不保证瘦身,它只是提供了一个隔离机制。真正决定体积的,是你在 builder 阶段有没有删掉 ~/.m2/repository 缓存、在 runner 阶段有没有误用带 shell 的镜像、以及 COPY 路径是否足够克制。这些细节不抠,镜像照样卡在 400MB 上下。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

10517

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

7642

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

6672

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1144

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

928

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1376

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2769

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

20071

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1235

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
OpenJDK项目Wiki
OpenJDK项目Wiki

共0课时 | 0人学习

OpenJDK构建指南
OpenJDK构建指南

共0课时 | 0人学习

OpenJDK官网文档
OpenJDK官网文档

共0课时 | 0人学习