如何减小 Docker 镜像体积?
构建的镜像太大,拉取和部署都很慢,想优化镜像体积
解决方案
使用多阶段构建 推荐
# Dockerfile 多阶段构建示例 FROM node:18 AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # 最终镜像只包含运行时需要的文件 FROM node:18-alpine AS production WORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules CMD ["node", "dist/main.js"]
多阶段构建将构建环境和运行环境分离。最终镜像只包含运行时必要的文件,不包含编译工具、源码和开发依赖。
适用场景:需要编译/构建步骤的应用(Go、Java、TypeScript 等)
选择更小的基础镜像 推荐
# 对比不同基础镜像大小: # node:18 ~900MB # node:18-slim ~200MB # node:18-alpine ~170MB # 使用 alpine 版本 FROM node:18-alpine # 或使用 distroless(更安全更小) FROM gcr.io/distroless/nodejs18-debian12
alpine 基于 musl libc,体积极小。distroless 镜像不包含 shell 和包管理器,更安全但调试不便。
适用场景:基础镜像选择阶段,或现有镜像体积过大
优化 Dockerfile 层和依赖
# 合并 RUN 命令减少层数
RUN apt-get update && \
apt-get install -y --no-install-recommends curl && \
rm -rf /var/lib/apt/lists/*
# 只安装生产依赖
RUN npm ci --only=production
# 使用 .dockerignore 排除不需要的文件
# .dockerignore 内容:
# node_modules
# .git
# *.md
# tests/每个 RUN 创建一层,合并命令减少层数。安装后清理缓存,只装生产依赖,用 .dockerignore 排除无关文件。
适用场景:已经用了 alpine 但镜像仍然较大
注意事项
alpine 使用 musl libc,某些依赖可能不兼容
distroless 镜像没有 shell,无法 exec 进入调试
多阶段构建注意 COPY --from 的路径要正确