Score:1

Docker Stack Deploy doesn't resolve environment variables with default value like Docker Compose does

hm flag

I have the following example files

docker-compose.yml

version: '3'
services:
  web:
    image: webapp:${VARIABLE_A:-${VARIABLE_B}}

env.conf

VARIABLE_B=123

VARIABLE_A is not set on purpose so it should fall back to VARIABLE_B

Docker compose is able to resolve the default value of the environment variable, however docker stack deploy is unable to do the same resolution

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

As you can see when using docker stack deploy it detects ${VARIABLE_A:-${VARIABLE_B}} is an environment variable that, because VARIABLE_A is not set, it should default to ${VARIABLE_B} however it does not resolve its value which is 123

Obviously, webapp does not exist, it's only an example, but the above error output should be this instead

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

Why does this happen? Is there any workarounds for this?

Score:1
es flag

For reference see in moby docker stack deploy in 1.13 doesn't load .env file as docker-compose up does. Specifically Comment from kinghuang

"I have my developers use docker-compose config to pre-process Docker Compose projects before passing them to docker stack deploy. You can do this in one line with:

docker stack deploy -c <(docker-compose config) stack-name-here

That way, all Docker Compose features including .env processing are fully applied."

RabidTunes avatar
hm flag
I haven't tested this solution, but I'll mark it as valid since it looks way cleaner than what I ended up doing
Score:0
hm flag

The workaround i ended up doing for docker stack deploy is using envsubst to replace env vars

user@laptop:~$ env $(cat ./env.conf | xargs) envsubst < ./docker-compose.yml | docker stack deploy --compose-file - stack

Documentation says that by using --compose-file - it takes the stdin as the docker compose file, so basically what this does is to first resolve all the variables in the docker-compose.yml then pass the result using a pipe to docker stack deploy

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.