Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Environment variable assignment in Docker Compose - colon way

This is the question about docker-compose.yml file syntax. I met the variable assignment like this on the internet:

environment:
    PMA_HOST: mysql

http://tech.osteel.me/posts/2017/01/15/how-to-use-docker-for-local-web-development-an-update.html


On the other hand the documentation tells like this:

environment:
  - DEBUG=1

https://docs.docker.com/compose/environment-variables/

Is the way without the dash and with the colon proper? What is the difference?

like image 749
trzczy Avatar asked Mar 30 '17 00:03

trzczy


People also ask

Can I use environment variables in Docker compose file?

It seems that docker-compose has native support now for default environment variables in file. all you need to do is declare your variables in a file named . env and they will be available in docker-compose.

How do I set an environment variable in docker?

Use -e or --env value to set environment variables (default []). If you want to use multiple environments from the command line then before every environment variable use the -e flag. Note: Make sure put the container name after the environment variable, not before that.

Does Docker compose override environment variables?

But docker-compose does not stop at the . env and the host's current environment variables. It's cool that you can simply override values of your . env file, but this flexibility is can also be the source of nasty bugs.


1 Answers

The documentation itself says both methods are working:

You can use either an array or a dictionary.

Now let's forgive Docker for failing to use the proper terminology (an array is actually a sequence in YAML, a dictionary is a mapping) and have a look from the YAML perspective:

A mapping is part of the YAML syntax and therefore parsed by the YAML parser, which enables a syntax-aware editor to do proper highlighting and such. Like the docs say, values like true and false will be converted to a boolean by YAML, so you need to be aware of that. Example from docs:

environment:
  RACK_ENV: development
  SHOW: 'true'
  SESSION_SECRET:

Would we not quote 'true', it would be parsed as a boolean value, which is not what we want.

Using a sequence on the other hand leaves the space of YAML syntax. The sequence itself is YAML, but the values are just parsed as one scalar each. For example, the first scalar value in the sequence here:

environment:
  - RACK_ENV=development
  - SHOW=true
  - SESSION_SECRET

Will be parsed by YAML as RACK_ENV=development. Docker will do post-processing to separate variable name from value. So using this method means that you are using two parsing steps, which makes it more difficult for a syntax-aware editor to properly highlight it. Also, you impose on the user the decision about where to use = and where :, which is not immediately obvious for people who don't know YAML well. It can confuse people.

Looking at escaping, the true does not need to be quoted anymore. This is because it is in the middle of a YAML scalar and therefore is not parsed as standalone value. In fact, quoting it would make YAML treat the quotes as content.

This also means that if you need quoting (for example because you want to use escape sequences), you need to quote the whole scalar. For example, if you want to have a tab character inside your value, it'll look like this:

environment:
  - "MY_VAR=some\tvalue"

It will not work if you only quote the part after =. Again, this may be confusing.

Conclusion: For me it seems that using a mapping is more consistent and confuses the user less, and it is therefore preferable. ymmv.

like image 76
flyx Avatar answered Oct 01 '22 15:10

flyx