Docker 镜像瘦身:多阶段构建 + .dockerignore 的实际收益

举报
yd_241226763 发表于 2026/11/04 09:53:56 2026/11/04
【摘要】 很多团队第一次把 Go 或 Python 服务打成镜像,都会得到一个几百 MB 甚至上 GB 的“全家桶”。本文用一组实测数据说明:多阶段构建加上 .dockerignore,通常能把镜像体积压到原来的十分之一左右。一、镜像为什么会变大镜像体积主要来自三块:基础镜像、构建工具链、构建上下文。用 ubuntu:22.04 做底子,光系统层就有 70 多 MB;编译时用到的 gcc、make、头...

很多团队第一次把 Go 或 Python 服务打成镜像,都会得到一个几百 MB 甚至上 GB 的“全家桶”。本文用一组实测数据说明:多阶段构建加上 .dockerignore,通常能把镜像体积压到原来的十分之一左右。


一、镜像为什么会变大


镜像体积主要来自三块:基础镜像、构建工具链、构建上下文。用 ubuntu:22.04 做底子,光系统层就有 70 多 MB;编译时用到的 gcc、make、头文件和包管理器缓存会原样进入镜像层。更隐蔽的是构建上下文:如果目录里躺着 node_modules、.git、日志和测试数据,一句 COPY . . 会把它们全部打进镜像——即使后面再删除,也只是在新层里“标记删除”,体积并不会减少。


二、多阶段构建:编译环境不带上线


思路很简单:第一阶段用完整 SDK 镜像编译,第二阶段只把产物拷进精简运行镜像。以 Go 为例:第一阶段 FROM golang:1.22 AS builder,COPY 后执行 go build -o app .;第二阶段 FROM alpine:3.20,用 COPY --from=builder 只拷贝二进制。golang:1.22 超过 800 MB,alpine:3.20 只有 7 MB,最终镜像通常不到 20 MB。注意静态编译时要加 CGO_ENABLED=0,避免 alpine 缺 glibc 起不来。


Python 项目同理:第一阶段 pip install 到虚拟环境并编译 wheel,第二阶段用 python:3.12-slim 拷贝 site-packages,一般能从 1 GB 降到 200 MB 以内。


三、.dockerignore:先把上下文打扫干净


.dockerignore 的语法和 .gitignore 一致,放在 Dockerfile 同目录。一个实用起点:.git、node_modules、__pycache__、*.log、tests、docs、.venv。这一步不仅省体积,还能明显加快 build context 的上传速度——机器学习项目里几十 GB 的数据集,绝不该出现在 docker build 的输出里。


四、实测收益


同一个 Go 服务:单阶段、ubuntu 底镜像 856 MB;改成多阶段 + alpine + .dockerignore 后 18 MB,拉取时间从 40 秒降到 2 秒。镜像小了,K8s 滚动发布更快,本地和 CI 的缓存占用也更低。


五、小结


先写 .dockerignore 打扫上下文,再用多阶段构建分离编译与运行,最后选 slim/alpine 基础镜像。三步做完,多数服务的镜像能缩到原来的十分之一,这是性价比最高的容器优化手段。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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