多阶段构建可将Nginx镜像压至100MB以内:builder阶段编译、base阶段装运行依赖、final阶段仅复制二进制与配置;选Alpine但精简非必需包,用--no-cache,分层对齐变更频率,最终可选scratch或最小Alpine并删除文档/本地化文件。

直接用多阶段构建 + 精简依赖,就能把 Nginx 镜像从几百 MB 压到 100MB 以内,甚至更低。关键不是“能不能做”,而是每一步是否真正剥离了构建时才需要的东西。
多阶段构建必须拆清三个角色
一个阶段只干一件事,不能混用:
-
builder 阶段:装 Go 编译器、下载依赖、编译
nginx-ingress-controller二进制(如果是 ingress-nginx);或装 gcc/pcre/zlib/make,解压编译源码版 Nginx(如果是自建 Nginx) -
base 阶段:仅安装运行必需的系统级依赖,比如
ca-certificates、tzdata,用--no-cache避免残留 apk 缓存 - final 阶段:只 COPY 编译好的二进制、预构建的 nginx 目录、配置文件,不带任何构建工具链、源码、.o 文件
基础镜像选 Alpine 但别盲目信任默认包
Alpine 小是小,但官方 Dockerfile 常会多装一堆非必需包。比如:
-
bash可换成ash(Alpine 默认 shell),删掉 bash 节省约 5MB -
patch、git、curl、libxml2、grpc-cpp这类,除非你明确要用 gRPC 健康检查或 XML 配置解析,否则全可剔除 - 用
apk add --no-cache替代apk add && apk del,避免缓存层残留
分层和缓存要对齐变更频率
高频修改的内容(如应用代码、配置)要放在低层之后,让 Docker 缓存更有效:
- 先 COPY
go.mod和go.sum,再go mod download—— 依赖不变时这层完全复用 - 源码
COPY . .放在最后,避免每次改一行代码就重跑整个编译 - 不要把
RUN apk add和COPY nginx.conf写在同一层,否则改配置也会触发重装包
最终镜像里连 ls 都可以不要(可选激进策略)
如果只跑 Nginx 服务、不进容器调试,还能进一步瘦身:
- 用
scratch作 final 阶段基础镜像(需静态编译 Nginx 或 controller) - 或保留最小 Alpine,但只 COPY 二进制 + nginx 目录 + 必需的 so 库(用
ldd检查) - 删除所有文档、man、locale(
apk del --purge后清理 /usr/share /usr/doc)


















