Docker Stack Deploy 不会像 Docker Compose 那样解析具有默认值的环境变量

Docker Stack Deploy 不会像 Docker Compose 那样解析具有默认值的环境变量

我有以下示例文件

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"

在此链接中如何在docker swarm堆栈中传递环境变量

您将找到关于如何做到这一点的非常好的解释。我遇到了同样的问题,并以这种方式克服了它。问候

相关内容