You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Compose构建失败却返回0退出码,Makefile仍执行touch命令

问题

在Makefile的docker.build目标中定义了如下命令:

docker.build:
	BUILDKIT_PROGRESS=plain docker compose build && touch docker.build || rm -f docker.build

当Dockerfile的构建阶段(比如gateway-builder阶段执行RUN exit 1这类失败命令)出现错误时,控制台明明显示构建失败,但Make却执行了touch docker.build而非rm -f docker.build。使用Docker 23.0.5,尝试过Make 4.3和4.4.1版本,询问该问题的原因。

原因分析

这个问题由两方面因素共同导致:

  1. Shell逻辑运算符的执行规则:你写的A && B || C命令等价于(A && B) || C,只有当A(即docker compose build)执行失败(退出码非0)时,才会触发||后的rm操作;如果A返回退出码0,就会执行touch操作。
  2. Docker 23.0.5的BuildKit退出码问题:在该版本中,当使用BuildKit进行多阶段构建时,若某个中间构建阶段(如gateway-builder)执行失败,docker compose build会在控制台输出失败日志,但错误地返回退出码0。这让Shell误以为A执行成功,因此执行了touch docker.build,而非预期的删除操作。

你可以直接在终端执行BUILDKIT_PROGRESS=plain docker compose build; echo $?验证:如果构建失败但输出的退出码是0,就可以确认是这个问题。

解决方法

改用if-else逻辑代替&&/||的组合,直接判断命令的退出码,确保逻辑不受异常退出码影响:

docker.build:
	BUILDKIT_PROGRESS=plain docker compose build; \
	if [ $$? -eq 0 ]; then \
		touch docker.build; \
	else \
		rm -f docker.build; \
	fi

内容的提问来源于stack exchange,提问作者user3534080

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 00:47:38