Docker 构建(docker build)失败时如何调试?

调试构建失败五步走:读报错定位失败层、用 --progress=plain 看完整输出、--no-cache 排除缓存干扰、将失败前内容单独构建为命名阶段,再起临时容器手动执行、检查 .dockerignore 与上下文。本文详解每一步。

最佳实践
Docker 构建(docker build)失败时如何调试?封面

调试思路:构建失败可能来自指令执行、语法解析、上下文、网络或存储等阶段,不一定有命令退出码。按顺序做:①仔细看报错中失败的指令与输出;②--progress=plain 拿完整日志;③--no-cache 排除缓存干扰;④利用缓存到失败点之前,起一个临时容器手动执行失败命令交互排查;⑤检查构建上下文与 .dockerignore。

第一步:读报错信息

RUN 命令失败时,报错通常会写明指令和退出码:

ERROR: process "/bin/sh -c apt-get install -y curl" did not complete successfully: exit code: 100

退出码上方那段输出才是真正的错误(如包不存在、网络超时)。

第二步:拿完整输出

BuildKit 默认的进度输出会折叠日志,加参数看全文:

docker build --progress=plain -t myapp .

第三步:排除缓存干扰

缓存层可能掩盖或引入问题:

docker build --no-cache --pull -t myapp .

--no-cache 不复用普通构建层,但不会自动清空 cache mount 内容;--pull 请求检查基础镜像的新版本。

第四步:进临时容器手动复现(杀手锏)

利用缓存——失败点之前的层都是现成的。BuildKit 日志中的缓存记录 ID 不保证可直接运行。可把失败点之前的内容命名为 debug-base 阶段,再单独构建:

# Dockerfile 中将失败前内容组织为 debug-base 阶段
# 失败命令放入后续 FROM debug-base AS final 阶段
docker buildx build --load --target debug-base -t myapp:debug .
docker run --rm -it --entrypoint /bin/sh myapp:debug
# 容器里手动执行失败的命令,交互式排查
apt-get install -y curl

运行时容器不等于构建沙箱,构建参数、secret/cache mounts、网络和平台配置仍需对应核对;镜像也必须包含所用 shell。

第五步:检查上下文与常见原因

常见原因 表现 处理
COPY 的文件不在上下文 not found 确认文件在构建上下文内,查 .dockerignore 是否误排除
网络/源问题 apt/pip 超时 换国内镜像源、配代理
架构不匹配 exec format error 选择目标平台,并确认构建节点或仿真支持;仅加 --platform 不保证可执行
指令语法错 unknown instruction 检查大小写、续行符
磁盘满 no space left docker system prune

常见问题(FAQ)

Q:本地能构建、CI 上失败?
A:多数是本地缓存掩盖(用 --no-cache 复现)、上下文不同(CI 的 checkout 少了文件)或架构不同(ARM Mac vs x86 CI)。

Q:多阶段构建里前面阶段失败怎么看?
A:--target 阶段名 只构建到该阶段,分段定位。

Q:如何验证 Dockerfile 语法但不构建?
A:用 docker build --check(BuildKit 提供的 lint),或 hadolint 工具静态检查。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台