多阶段构建把服务镜像从 1.4G 压到 86M

举报
yd_275379215 发表于 2026/11/02 10:25:04 2026/11/02
【摘要】 CI机器扩了两轮还是慢,一看产物:一个Go服务镜像1.4G。打开Dockerfile,原因很直白:把整个构建镜像连同源码、工具链一起打包进了最终镜像。多阶段构建改造后86M。原始写法的问题:基础镜像用ubuntu:22.04,COPY全部源码进去,在容器里gobuild,最后也没清理任何中间产物。改造后:#----构建阶段----FROMgolang:1.22-alpineASbuilder...

CI 机器扩了两轮还是慢,一看产物:一个 Go 服务镜像 1.4G。打开 Dockerfile,原因很直白:把整个构建镜像连同源码、工具链一起打包进了最终镜像。多阶段构建改造后 86M。

原始写法的问题:基础镜像用 ubuntu:22.04,COPY 全部源码进去,在容器里 go build,最后也没清理任何中间产物。改造后:

# ---- 构建阶段 ----
FROM golang:1.22-alpine AS builder
WORKDIR /src
COPY go.mod go.sum ./
RUN go mod download                # 依赖层单独缓存
COPY . .
RUN CGO_ENABLED=0 go build -ldflags '-s -w' -o /out/app ./cmd/api

# ---- 运行阶段 ----
FROM alpine:3.20
RUN adduser -D -u 10001 app
COPY --from=builder /out/app /usr/local/bin/app
USER 10001
ENTRYPOINT /usr/local/bin/app

三处关键:依赖先 COPY go.mod 再下载,代码变动不破坏缓存层;-ldflags -s -w 去掉调试符号,二进制小 30%;运行阶段不带编译器和源码。

再进一步把 alpine 换 distroless 或 scratch,能到 30M 以内,但要接受没有 shell 进容器排查的不便,我们保守用了 alpine。

前端 Node 项目同理:构建阶段跑 npm ci 和 npm run build,运行阶段只把 dist 拷进 nginx 静态目录,从 1.1G 降到 25M。

镜像瘦身的收益不只是存储:拉取快、攻击面小、启动快。改造完,发布单次镜像传输时间从 90 秒降到 12 秒,几百个服务的累积效应非常可观。顺手在 CI 里加了卡点:镜像超过 300M 直接失败,防止它慢慢胖回去。

补充一个容易被忽略的收益维度:镜像变小后,仓库的存储和带宽费用也降了,我们 Harbor 集群的月度出口流量降了四成,这笔账多数团队从没算过。镜像优化是那种每个环节都受益的改造,值得作为新人练手项目,产出立竿见影。

镜像治理的最后一步是基础镜像的统一维护:团队公共基础镜像每月定期重建,安全补丁自动合入,业务镜像跟着触发重建,漏洞存量长期压在低位。有同学担心重建影响稳定性,实践下来只要基础镜像版本号固定、变更内容只有补丁,风险完全可控。镜像这件事,管住入口比事后清理便宜太多,一个卡点加一条保留策略,就够大多数团队用好几年。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。