Docker 镜像瘦身:从 1.2GB 到 89MB 的全过程

Docker Image Diet: From 1.2GB to 89MB Step by Step

| Kevin | 2026-08-25T10:14:42

团队的 Java 项目 Docker 镜像居然有 1.2GB,每次部署拉取镜像都要好几分钟。一番折腾之后成功减到了 89MB。

Our Java project Docker image was 1.2GB, making deployments painfully slow. After optimization, we reduced it to 89MB.

我们有个 Spring Boot 项目的 Docker 镜像之前是 1.2GB,每次 CI/CD 推送到镜像仓库要好几分钟,生产环境拉取也慢。花了半天时间一步步优化,最终压到了 89MB。 原来的 Dockerfile FROM openjdk:17 COPY target/app.jar /app.jar EXPOSE 8080 CMD ["java", "-jar", "/app.jar"] 问题很明显:openjdk:17 这个基础镜像本身就有 470MB,再加上 Spring Boot 的 fat jar,轻轻松松就上 GB 了。 第一步:换基础镜像 把 openjdk:17 换成 eclipse-temurin:17-jre-alpine,基础镜像从 470MB 降到 100MB。注意用 JRE 不用 JDK,运行时不需要编译工具。 第二步:多阶段构建 # 构建阶段 FROM eclipse-temurin:17-jdk-alpine AS builder WORKDIR /build COPY pom.xml . RUN mvn dependency:go-offline COPY src ./src RUN mvn package -DskipTests # 运行阶段 FROM eclipse-temurin:17-jre-alpine COPY --from=builder /build/target/app.jar /app.jar EXPOSE 8080 CMD ["java", "-jar", "/app.jar"] 这样最终镜像里就不会包含 Maven、源码、.m2 缓存这些构建时的东西了。镜像大小降到了 230MB。 第三步:Spring Boot 分层 Spring Boot 2.3+ 支持分层 jar,可以把依赖和应用代码分开。这样每次代码改动只需要重新构建应用层,依赖层走 Docker 缓存。 FROM eclipse-temurin:17-jre-alpine WORKDIR /app COPY --from=builder /build/target/extracted/dependencies/ ./ COPY --from=builder /build/target/extracted/spring-boot-loader/ ./ COPY --from=builder /build/target/extracted/snapshot-dependencies/ ./ COPY --from=builder /build/target/extracted/application/ ./ ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"] 第四步:jlink 自定义 JRE 杀手锏来了。用 jlink 只打包项目实际用到的 Java 模块,定制一个最小 JRE: RUN jlink --add-modules java.base,java.logging,java.sql,java.naming,java.management,java.instrument,java.desktop,java.security.jgss --strip-debug --no-man-pages --no-header-files --compress=2 --output /custom-jre 定制 JRE 只有 50MB,比完整 JRE 的 100MB 又少了一半。最终镜像大小:89MB。 对比 阶段大小 原始1.2GB 换 Alpine JRE230MB 分层构建230MB(但增量更新很快) jlink 定制 JRE89MB


Our Spring Boot Docker image was 1.2GB. After a half-day of optimization, we got it down to 89MB. Steps Switch base image from openjdk:17 (470MB) to eclipse-temurin:17-jre-alpine (100MB) Multi-stage build to exclude build tools from final image Spring Boot layered jars for better Docker cache utilization jlink custom JRE with only needed modules (50MB vs 100MB full JRE) Results 1.2GB → 89MB. CI/CD push time dropped from minutes to seconds. Production pulls became nearly instant.

← Back to News