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?

3 Answers 3

2

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

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 Commented Aug 27, 2023 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

0

Here is another nice way how you can overcome this problem. You have to create a ".env" file with all the variables you want to add to the environment for example: APP_NAME=Example . Then in your stack-compose.yml you can declare it like this:

version: "3.9" services: myservice: env_file: - .env 

After this, you should run the following command:

docker stack config -c stack-compose.yml | docker stack deploy -c - mystackname 

Which will insert the variables that you declared in the .env file in the stack_compose.yml like this:

version: "3.9" services: myservice: environment: APP_NAME: "Example" 

In this link How to pass env variables in docker swarm stack

You will find a very good explanation of how to do this. I had the same problem and overcame it this way. Regards

2
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review Commented Feb 9, 2024 at 15:54
  • Hey @DaveM thanks for your comment. I improved my answer based on the link explanation. Regards Commented Feb 9, 2024 at 16:24

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.