为什么docker-compose --build-arg无法覆盖yml中的EMP_BUILD_LOCALLY变量?
问题描述
我有一个带参数的.bat脚本用于执行docker-compose build命令:
... set "Build=Build" set "PublishConfig=Debug" ... docker-compose -f backend.yml --env-file ./.env build --build-arg EMP_PUBLISH_CONFIG=%PublishConfig% --build-arg EMP_BUILD_LOCALLY=%Build% ...
.env文件中的变量配置:
EMP_PUBLISH_CONFIG=Release EMP_BUILD_LOCALLY=""
.yml文件配置:
version: "3.7" ... services: customers: container_name: emp-customers build: context: ./../../ dockerfile: ./ci/local/backend/Dockerfile${EMP_BUILD_LOCALLY} target: emp-customers
同时存在如DockerfileBuild和Dockerfile等多个Dockerfile,其中一个Dockerfile内容如下:
ARG EMP_PUBLISH_CONFIG=Release FROM deploy AS emp-customers COPY Src/Customers/Emp.Customers.WebApi/bin/$EMP_PUBLISH_CONFIG/net6.0/linux-x64/publish /app/Emp.Customers.WebApi
目前EMP_PUBLISH_CONFIG变量可通过.bat正常覆盖,但EMP_BUILD_LOCALLY仅使用.env中的值。请问这是什么原因,以及如何通过.bat覆盖该变量?
原因分析
EMP_PUBLISH_CONFIG是作为**构建参数(build-arg)**传递给Dockerfile内部使用的,docker-compose会把--build-arg的值传递给Dockerfile中的ARG指令,属于镜像构建阶段的变量,因此能正常覆盖。EMP_BUILD_LOCALLY是在docker-compose.yml的解析阶段被使用的(用来拼接Dockerfile文件名),这个阶段发生在docker-compose启动镜像构建流程之前,--build-arg参数仅在镜像构建阶段生效,无法影响yml文件的解析逻辑。所以yml会优先读取.env文件中的EMP_BUILD_LOCALLY值。
解决方法
要覆盖yml解析阶段使用的环境变量,需要在调用docker-compose之前,在bat脚本中直接设置系统环境变量,让docker-compose在解析yml时优先读取这个值:
修改后的bat脚本如下:
... set "Build=Build" set "PublishConfig=Debug" :: 直接设置环境变量,供docker-compose解析yml时读取 set "EMP_BUILD_LOCALLY=%Build%" ... docker-compose -f backend.yml --env-file ./.env build --build-arg EMP_PUBLISH_CONFIG=%PublishConfig% ...
补充说明:
- docker-compose解析yml时,会优先读取当前shell的环境变量,再读取.env文件中的值,因此脚本中设置的
EMP_BUILD_LOCALLY会覆盖.env中的对应值。 - 如果脚本执行完毕后不需要保留这个环境变量,可以在脚本末尾添加
set EMP_BUILD_LOCALLY=来清除它。
内容的提问来源于stack exchange,提问作者Vladimir
相关产品推荐
相关产品推荐

