Docker多阶段构建传入多个--build-arg失败,请求排查原因
问题分析与解决方案
你的问题出在Docker多阶段构建中ARG的作用域规则,而不是docker build命令本身。
核心原因
Docker的ARG变量有明确的作用域限制:
- 在所有
FROM指令之前声明的ARG是全局变量,可在所有构建阶段(每个FROM对应一个独立阶段)中使用。 - 在某个
FROM之后声明的ARG,仅属于当前构建阶段,当切换到下一个FROM(新阶段)时,该变量会直接失效。
看你原来的Dockerfile:
ARG IMAGE_ONE FROM ${IMAGE_ONE} RUN cat /etc/debian_version ARG IMAGE_TWO # 这个ARG仅属于第一个构建阶段 FROM ${IMAGE_TWO} # 进入第二个阶段时,IMAGE_TWO变量已不存在,无法被解析 RUN cat /etc/debian_version
构建输出里Step 5/6 : FROM ${IMAGE_TWO}后面显示空的--->,说明${IMAGE_TWO}完全没被替换,Docker尝试基于一个空镜像构建,自然会出现找不到/bin/sh的错误。
修复后的Dockerfile
把IMAGE_TWO的ARG声明移到所有FROM之前,作为全局变量即可:
# 全局ARG,所有构建阶段都能访问 ARG IMAGE_ONE ARG IMAGE_TWO FROM ${IMAGE_ONE} RUN cat /etc/debian_version FROM ${IMAGE_TWO} RUN cat /etc/debian_version
验证构建
用你原来的构建命令就能成功执行:
docker build --no-cache --build-arg IMAGE_ONE=debian:7 --build-arg IMAGE_TWO=debian:8 .
此时两个阶段会分别使用指定的镜像,依次输出7.11和8.11(debian:8的版本号)。
补充小技巧
如果需要给ARG设置默认值,可在声明时直接指定,这样即使构建时不传递--build-arg参数,也能使用默认镜像:
ARG IMAGE_ONE=debian:latest ARG IMAGE_TWO=ubuntu:latest
内容的提问来源于stack exchange,提问作者segfault
相关产品推荐
相关产品推荐

