docker-compose构建时ENVIRONMENT变量偶发被替换为0问题咨询
问题原因
- 核心原因是你使用的Docker服务端19.03.14版本存在已知的多ARG变量解析bug:当Dockerfile中连续定义多个ARG参数时,偶发会出现后续ARG的数值覆盖前面ARG取值的问题,你的配置中
enablecron的值为0,因此ENVIRONMENT参数会偶发被错误覆盖为0,导致ADD指令寻址到不存在的config.0.xml文件。 - Docker客户端20.10和服务端19.03跨大版本通信,存在构建参数传递的兼容问题,偶发
ENVIRONMENT参数没有正确传递到服务端构建进程,部分旧版本Docker对未定义变量的替换逻辑异常,会返回默认数值0。 - 偶发问题还可能和构建缓存有关:如果之前有过
ENVIRONMENT=0的错误构建记录,Docker会复用错误的缓存层,导致不修改配置的情况下也会随机出现报错。
解决方案
升级Docker服务端版本
将服务端Docker升级到20.10+版本,和客户端版本保持一致,既可以修复原生ARG解析bug,也能解决跨版本API通信的兼容问题,是最彻底的解决方式。调整Dockerfile的变量使用逻辑,避开指令层变量解析
不要在ADD指令中直接使用ARG变量,改为先把整个配置目录复制到构建环境中,再通过RUN指令在容器内部完成文件复制,RUN指令由容器内shell解析变量,不会出现daemon层的解析bug:
# 原ADD ./config/config.${ENVIRONMENT}.xml /var/www/config.xml 替换为以下两行 ADD ./config/ /tmp/build_config/ RUN cp /tmp/build_config/config.${ENVIRONMENT}.xml /var/www/config.xml
- 添加变量默认值+显式传递参数
在Dockerfile中给ARG参数设置默认值,避免参数传递失败时出现异常取值:
# 修改ARG定义,添加默认值 ARG ENVIRONMENT=preprod
运行构建命令前可以显式导出环境变量,避免docker-compose没有加载到.env文件的问题:
export environment=preprod docker-compose build --no-cache
添加--no-cache参数禁用构建缓存,避免复用之前的错误缓存层。
- 固定docker-compose的构建参数传递格式
修改docker-compose.yml中args的写法,用键值对格式代替数组格式,避免解析异常:
myservice: image: ${REGISTRY}:5000/myservice build: context: myservice/ args: ENVIRONMENT: ${environment} enablecron: 0
内容的提问来源于stack exchange,提问作者blue112
相关产品推荐
相关产品推荐

