Docker 镜像构建为什么慢:一次 .dockerignore 排查

举报
yd_219824599 发表于 2026/10/24 00:25:29 2026/10/24
【摘要】 上周把一个 Python 小服务从本地搬到云主机,docker build 的第一行日志永远是:改一行 print 也要等 70 秒。查下来既不是网络问题,也不是机器太弱(2C4G),而是构建上下文被塞满了不该进去的东西:项目根目录下躺着 .venv/(三百多 MB 的虚拟环境)、node_modules/、.git/,还有几份训练用的数据集。默认情况下,Docker 会把构建目录里所有文件...

上周把一个 Python 小服务从本地搬到云主机,docker build 的第一行日志永远是:




改一行 print 也要等 70 秒。查下来既不是网络问题,也不是机器太弱(2C4G),而是构建上下文被塞满了不该进去的东西:项目根目录下躺着 .venv/(三百多 MB 的虚拟环境)、node_modules/、.git/,还有几份训练用的数据集。


默认情况下,Docker 会把构建目录里所有文件打包成 build context 发给 daemon,再逐层计算缓存。文件越多,发送越慢,缓存也越容易被无关文件的变化冲掉。


更要紧的是缓存判定:COPY . . 这一层的输入是「整个上下文的内容签名」,只要上下文中任意文件变动——包括 .git 里 ref 的变化——这一层就失效,后面的 RUN pip install 全部重跑。于是就出现「我明明没动依赖,它又把依赖装了一遍」。


解法是在项目根目录加一个 .dockerignore:




改完再看一眼上下文大小:




同一台机器、同一个项目的对比:


•上下文:412.6MB → 1.8MB

•首次构建:3 分 12 秒 → 48 秒

•只改一行业务代码:70 秒 → 6 秒(依赖层命中缓存)


顺手把 Dockerfile 里 COPY 的顺序也理了一下:




先 COPY 依赖清单再装依赖,最后 COPY 源码。改代码不碰依赖层,缓存能一直命中。


两点踩坑提醒:


1).dockerignore 里写 data/ 只忽略该目录及其子项;想递归匹配扩展名要用 **/*.log 这种写法,写 *.log 不保证覆盖子目录。


2).git 一定要排除,不只是为了体积——CI 里 checkout 之后 .git 的 index、远端 ref 每次都可能变,会让 COPY . . 的缓存频繁失效,这是「本地快、流水线慢」最常见的原因之一。


另外别把 requirements.txt、src/ 这类构建必需路径写进 .dockerignore,一旦写错,报错发生在 COPY 阶段,很容易误判成路径写错,排查方向会跑偏。


改完之后这个镜像再没出现过构建超时,机器还是那台 2C4G。

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

评论(0)

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

全部回复

上滑加载中

设置昵称

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

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

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