构建失败怎么定位
构建失败先要定位到“哪一步失败”,而不是盯着最后一行报错。BuildKit 默认把并行步骤的日志折叠,只留下失败的那条摘要,因此第一步是用 --progress=plain 拿到完整输出,再从第一个真实的报错位置往下看。高频原因集中在四类:COPY 的文件不在构建上下文或被忽略文件规则排除、构建期网络与依赖源不可达、基础镜像拉取失败、本地与目标平台架构不一致。把构建期问题与运行期问题分开治理,能省下大量反复试错的时间。
基本信息
| 完整日志 | docker build --progress=plain,BuildKit 默认折叠中间步骤输出 |
|---|---|
| 适用平台 | Docker 20.10 起默认启用 BuildKit,老版本可用 DOCKER_BUILDKIT=1 临时开启 |
| 构建上下文 | docker build 末尾那个目录,COPY 只能取其中的文件 |
| 忽略规则 | .dockerignore 会静默排除文件,是 COPY not found 的高频原因 |
| 网络 | 构建期不会自动继承宿主代理,apt/npm/pip 需传构建参数或换内网源 |
| 架构 | exec format error 表示基础镜像或预编译二进制与目标平台不一致 |
典型使用场景
- 排查 COPY 报错:确认文件是否真在构建上下文里、是否被 .dockerignore 排除
- 排除缓存干扰:加 --no-cache 重跑,或先确认改动是否让目标层真正失效
- 内网构建失败:核对构建机的代理、私有源与 DNS,容器内网络与宿主并不相同
- 跨架构发布前验证:用 buildx 指定 --platform,提前暴露架构不匹配的问题
- 压缩上下文体积:把无关目录写进 .dockerignore,加快传输并减少缓存失效
- 区分构建期与运行期问题:构建错误停在某个 RUN 步骤,运行错误要去看容器日志
排查命令
排查命令
docker build --progress=plain -t app:debug . 2>&1 | tail -80 # 拿完整构建日志
docker build --progress=plain --no-cache -t app:debug . # 排除缓存干扰
docker buildx build --platform linux/amd64 -t app:debug . # 指定平台验证架构
docker build --network=host -t app:debug . # 构建期需要宿主网络时临时使用
cat .dockerignore # 确认要 COPY 的文件没被排除
docker buildx imagetools inspect nginx:1.27 # 查基础镜像包含哪些架构高频失败点
| 现象 | 常见原因 | 定位方法 |
|---|---|---|
| COPY failed: not found | 文件不在上下文或被忽略规则排除 | 核对上下文路径与 .dockerignore |
| exec format error | 基础镜像或二进制架构不符 | 用 imagetools 查看清单架构 |
| apt-get 连接超时 | 构建期无代理或源不可达 | 传构建参数设代理,或换内网源 |
| failed to solve | BuildKit 汇总错误 | 往上翻到第一个真实报错步骤 |
| no space left on device | 构建缓存与旧镜像占满磁盘 | docker system df 查看后清理 |
构建期与运行期分开看:构建错误止于某个 RUN 步骤,看的是它执行的输出;运行错误发生在容器启动之后,看容器日志与退出码更有用。
依赖安装类失败常与缓存有关:依赖清单没变就一直复用旧层,看似改了代码其实没重新拉依赖,需要改动依赖文件或加 --no-cache。
构建期网络与运行期网络是两套环境:构建机需要能访问包源,容器运行时还需要访问业务依赖,两者都要单独验证。