镜像瘦身不是追求最小数字,而是移除运行时不需要的编译器、包管理器和缓存,同时保留证书、时区和必要诊断能力。
使用多阶段构建
FROM golang:1.24 AS build
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -trimpath -o /out/app ./cmd/app
FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=build /out/app /app
USER nonroot:nonroot
ENTRYPOINT ["/app"]
构建依赖留在 builder 阶段,运行阶段只复制制品。基础镜像使用 digest 固定,并由自动化定期更新安全补丁。
控制上下文与层
配置 .dockerignore 排除 Git、测试数据和本地密钥。把依赖清单先复制以提高缓存命中,但不要为了少一层而牺牲可读性。
保留调试路径
Distroless 镜像没有 shell,应准备临时 debug 容器和完整 Runbook,而不是在生产镜像中重新加入工具。
验证结果
比较镜像大小、拉取时间、漏洞数量和启动时间,同时生成 SBOM 并签名。体积减少但丢失 CA 证书导致运行失败,不是有效优化。