我有以下示例文件
docker-compose.yml
version: '3'
services:
web:
image: webapp:${VARIABLE_A:-${VARIABLE_B}}
env.conf
VARIABLE_B=123
VARIABLE_A
不是故意设置的,所以应该回到VARIABLE_B
Docker compose 能够解析环境变量的默认值,但docker stack deploy
无法进行相同的解析
user@laptop:~$ docker compose --env-file ./env.conf convert
name: dockercomposetest
services:
web:
image: webapp:123
networks:
default: null
networks:
default:
name: dockercomposetest_default
user@laptop:~$ env $(cat ./env.conf | xargs) docker stack deploy --compose-file docker-compose.yml stack
Creating service stack_web
failed to create service stack_web:
Error response from daemon:
rpc error:
code = InvalidArgument desc = ContainerSpec: "webapp:${VARIABLE_B}" is not a valid repository/tag
正如您所看到的,当使用docker stack deploy
它时,它检测${VARIABLE_A:-${VARIABLE_B}}
到一个环境变量,因为VARIABLE_A
没有设置,它应该默认为,${VARIABLE_B}
但它不能解析它的值,即123
显然,webapp 不存在,这只是一个例子,但上面的错误输出应该是这个
user@laptop:~$ env $(cat ./env.conf | xargs) docker stack deploy --compose-file docker-compose.yml stack
Creating service stack_web
failed to create service stack_web:
Error response from daemon:
rpc error:
code = InvalidArgument desc = ContainerSpec: "webapp:123" is not a valid repository/tag
为什么会发生这种情况? 有什么解决方法吗?
答案1
请参阅 moby 中的参考内容1.13 版的 docker stack deploy 无法像 docker-compose up 那样加载 .env 文件。 具体来说kinghuang 的评论
“我让我的开发人员使用 docker-compose config 对 Docker Compose 项目进行预处理,然后再将它们传递给 docker stack deploy。你可以用一行代码完成此操作:
docker stack deploy -c <(docker-compose config) stack-name-here
这样,包括 .env 处理在内的所有 Docker Compose 功能都得到了充分应用。”
答案2
我最终采取的解决方法docker stack deploy
是使用envsubst
替换环境变量
user@laptop:~$ env $(cat ./env.conf | xargs) envsubst < ./docker-compose.yml | docker stack deploy --compose-file - stack
文档说,通过使用--compose-file -
它将stdin
作为docker compose文件,所以基本上它所做的就是首先解析中的所有变量,docker-compose.yml
然后使用管道将结果传递给docker stack deploy
答案3
这是解决此问题的另一种好方法。您必须创建一个“.env”文件,其中包含要添加到环境中的所有变量,例如:APP_NAME=Example
。然后在 stack-compose.yml 中,您可以像这样声明它:
version: "3.9"
services:
myservice:
env_file:
- .env
此后,您应该运行以下命令:
docker stack config -c stack-compose.yml | docker stack deploy -c - mystackname
它将把您在 .env 文件中声明的变量插入到 stack_compose.yml 中,如下所示:
version: "3.9"
services:
myservice:
environment:
APP_NAME: "Example"
您将找到关于如何做到这一点的非常好的解释。我遇到了同样的问题,并以这种方式克服了它。问候