速查·2.X 镜像依赖踩坑速查补遗(一) 正文 2.4 归档了"分层顺序、版本锁定、挂载保数据"三类高频坑。本条是镜像与依赖的补充踩坑:问题更隐蔽,出问题时报错离根因更远。 坑一:每次构建 pip 都全网重下,CI 慢得没法忍 现象:改一行代码重新 build,所有依赖重新下载,20 分钟起步。 根因: 的层缓存只对"完全相同的指令与上下文"有效,requirements.txt 一变就整体失效;且层缓存只在本地,CI 每次都是冷缓存。 处置:用 BuildKit 的 cache mount,缓存跨层、跨构建存活: 防止 pip 把缓存塞进镜像;cache mount 是给构建过程加速用的,两者不矛盾。
正文 2.4 归档了"分层顺序、版本锁定、挂载保数据"三类高频坑。本条是镜像与依赖的补充踩坑:问题更隐蔽,出问题时报错离根因更远。
现象:改一行代码重新 build,所有依赖重新下载,20 分钟起步。
根因:RUN pip install 的层缓存只对"完全相同的指令与上下文"有效,requirements.txt 一变就整体失效;且层缓存只在本地,CI 每次都是冷缓存。
处置:用 BuildKit 的 cache mount,缓存跨层、跨构建存活:
RUN --mount=type=cache,target=/root/.cache/pip \ pip install --no-cache-dir -r requirements.txt
--no-cache-dir 防止 pip 把缓存塞进镜像;cache mount 是给构建过程加速用的,两者不矛盾。
现象:同一个包 conda 装了一遍、pip 又装了一遍,import 到哪个全看缘分;卸载重装越修越乱。
根因:conda 和 pip 的包数据库互不知晓,同一个包留下两套元数据。
处置:立一条规矩——conda 只负责 Python 本身和编译型依赖(如 mkl),其余全部交给 pip;或者干脆纯 pip + 系统 apt。绝不混装同一个包。
现象:Dockerfile 一个字没改,构建忽然报 CUDA 版本对不上或包找不到。
根因:只有写全的具体 tag(如 nvidia/cuda:12.4.1-runtime-ubuntu22.04)才是钉死的;写了 :latest 或浮动 tag,官方某天推送新版本,你的构建环境就悄悄漂移了。
处置:生产 Dockerfile 锁具体版本 tag,更进一步可锁 digest(FROM nvidia/cuda@sha256:...)。升级镜像应该是显式的提交行为,而不是被动接受。
现象:构建报 "Unable to locate package xxx",明明昨天还能装。
根因:update 和 install 分层后,update 的结果被缓存;包列表是旧的,install 层在新环境下找不到新包名。
处置:合并成一条,并顺手清理索引:
RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential git && rm -rf /var/lib/apt/lists/*
现象:本地构建正常,CI 上报仓库不存在或权限拒绝。
根因:本地走的是你个人的 git 凭据,CI 既没有凭据也可能没有外网。
处置:私有依赖优先打成 wheel 放进内网制品库;实在要 git 拉取,用 build secret 注入 token,绝不能把 token 写进 Dockerfile(它会永久留在镜像历史里):
RUN --mount=type=secret,id=gittoken \ pip install git+https://$(cat /run/secrets/gittoken)@git.example.com/pkg.git
现象:服务器 df 一看,/var/lib/docker 占了几百 GB,新镜像都拉不动。
根因:每次构建产生的中间层、dangling 镜像、BuildKit 缓存从不自动清理。
处置:定期 docker system prune -a --filter "until=168h" 清一周前的产物;只清构建缓存用 docker builder prune。团队共享机器建议直接加定时任务。
现象:容器一启动就 exec format error 退出。
根因:多架构镜像在不同架构机器上默认拉取本地平台的层;构建机与运行机架构不一致时就会错位。
处置:构建和运行都显式声明平台:docker build --platform linux/amd64、docker run --platform linux/amd64。跨架构场景(如 Apple Silicon 上构建给服务器用)必须显式写。
详细原理见正文第二章 2.1「镜像分层设计」与 2.2「环境编排与可复现依赖」。