docker镜像瘦身核心是精简基础镜像、合并run命令并清理缓存、启用多阶段构建、合理copy及使用.dockerignore。优先选alpine或distroless,合并安装与清理至单层,分离构建与运行环境,避免冗余文件入镜。

通过合理设计 Dockerfile,可以显著减少镜像体积和层数,核心在于:精简基础镜像、合并 RUN 命令、清除构建中间产物、利用多阶段构建、避免复制无关文件。
选用极小基础镜像
优先使用 alpine 或更轻量的 distroless(如 gcr.io/distroless/java17)、scratch(仅适用于静态编译二进制)。避免用 ubuntu:22.04 或 openjdk:17-jdk 等臃肿镜像。
- Java 服务可用
eclipse/jetty:11-jre17-slim或azul/zulu-openjdk-alpine:17-jre - Go 服务编译后可直接 COPY 到
scratch镜像,体积常低于 10MB - 确认基础镜像已含所需运行时依赖(如 ca-certificates、tzdata),否则需显式安装
合并 RUN 指令并清理缓存
Docker 每条 RUN 都新增一层。应将安装、编译、清理写在同一 RUN 中,用 && 连接,并在末尾删除临时文件与包管理器缓存。
- 错误写法:
RUN apt-get update && apt-get install -y curl+RUN rm -rf /var/lib/apt/lists/*(产生两层) - 正确写法:
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/* - Node.js 项目示例:
RUN npm ci --only=production && npm cache clean --force
启用多阶段构建(Multi-stage Build)
将构建环境与运行环境分离:第一阶段用完整工具链编译打包,第二阶段仅 COPY 产出物到最小运行镜像。
- Java Maven 示例:build 阶段用
maven:3.9-openjdk-17编译 JAR;runtime 阶段用eclipse-jetty:11-jre17-slim并 COPY JAR - 前端项目:build 阶段用
node:18-alpine构建 dist;serve 阶段用nginx:alpineCOPY 静态资源 - 避免在 final 阶段保留
COPY --from=builder以外的任何构建依赖
控制 COPY 范围与忽略无用文件
使用 .dockerignore 排除源码中不需进镜像的文件(如 node_modules/、.git/、tests/、README.md),并尽量只 COPY 必需文件而非整个上下文。
- 推荐写法:
COPY package*.json ./→RUN npm ci --only=production→COPY src/ ./src/ - 避免
COPY . .,尤其当项目含大量日志、依赖或文档时 - 对 Java,只 COPY
target/*.jar,而非整个target/目录
不复杂但容易忽略:镜像瘦身不是堆砌技巧,而是从构建逻辑出发做减法——少一层 RUN、少一个包、少一个文件,最终叠加出可观的体积下降(常达 50%–80%)和层数收敛(从 20+ 层压至 3–5 层)。











