1

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?

RabidTunes
  • 125
  • 8

2 Answers2

1

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."

Simon
  • 126
  • 1
  • I haven't tested this solution, but I'll mark it as valid since it looks way cleaner than what I ended up doing – RabidTunes Aug 27 '23 at 11:58
0

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

RabidTunes
  • 125
  • 8