如何从Makefile传递变量到docker-compose?多条up命令仅首条执行怎么办
问题原因
- 你两次执行
docker-compose up -d时都没有指定要启动的单个服务,默认会尝试启动docker-compose.yaml里定义的所有服务 - 第一条命令仅传入了
PING_IMAGE_NAME、PING_IMAGE_TAG变量,启动id服务时缺少ID_IMAGE_NAME、ID_IMAGE_TAG变量,yaml模板渲染失败,命令返回非0错误码。Makefile默认遇到命令执行失败就会终止后续步骤,所以第二条命令根本不会运行 - 就算第一条执行成功,第二条命令仅传入ID相关变量,启动ping服务时也会缺少对应变量,依然会报错
临时修复方案
给每条docker-compose up命令加上对应要启动的服务名,就不会尝试启动另一个缺变量的服务:
# setting ping_image @PING_IMAGE_NAME="ping-svc:" PING_IMAGE_TAG="1.0" docker-compose up -d ping # setting id_image @ID_IMAGE_NAME="id-svc:" ID_IMAGE_TAG="1.0" docker-compose up -d id
更优实现方案
方案1:一次性传入所有变量启动全部服务
不需要分开两次执行,直接一条命令传全所有变量,一次性启动所有服务,写法更简洁:
@PING_IMAGE_NAME="ping-svc:" PING_IMAGE_TAG="1.0" \ ID_IMAGE_NAME="id-svc:" ID_IMAGE_TAG="1.0" \ docker-compose up -d
方案2:把镜像版本定义为Makefile变量,统一管理
如果后续还要加更多服务,把变量统一提到Makefile头部,维护更方便,也支持单独启动单个服务:
# 统一配置镜像信息 PING_IMAGE_NAME = ping-svc: PING_IMAGE_TAG = 1.0 ID_IMAGE_NAME = id-svc: ID_IMAGE_TAG = 1.0 # 启动所有服务 .PHONY: up up: @PING_IMAGE_NAME=$(PING_IMAGE_NAME) PING_IMAGE_TAG=$(PING_IMAGE_TAG) \ ID_IMAGE_NAME=$(ID_IMAGE_NAME) ID_IMAGE_TAG=$(ID_IMAGE_TAG) \ docker-compose up -d # 单独启动ping服务 .PHONY: up-ping up-ping: @PING_IMAGE_NAME=$(PING_IMAGE_NAME) PING_IMAGE_TAG=$(PING_IMAGE_TAG) docker-compose up -d ping # 单独启动id服务 .PHONY: up-id up-id: @ID_IMAGE_NAME=$(ID_IMAGE_NAME) ID_IMAGE_TAG=$(ID_IMAGE_TAG) docker-compose up -d id
方案3:使用.env文件管理变量
如果变量不需要经常动态修改,直接在docker-compose.yaml同级目录创建.env文件,docker-compose会自动读取里面的变量,不需要在Makefile里传:.env文件内容:
PING_IMAGE_NAME=ping-svc: PING_IMAGE_TAG=1.0 ID_IMAGE_NAME=id-svc: ID_IMAGE_TAG=1.0
Makefile就可以简化成:
.PHONY: up up: @docker-compose up -d
内容的提问来源于stack exchange,提问作者Md. Abu Farhad
相关产品推荐
相关产品推荐

