43

Defining a boolean in a docker-compose.yml file:

environment:
  SOME_VAR: true

and running docker up results in:

contains true, which is an invalid type, it should be a string, number, or a null

Attempts to solve the issue

  1. If true is changed to True the issue persists.
  2. Using 'true' is not accepted by the code itself (a play framework app is started using the ./target/universal/stage/bin/APPNAME -Dplay.evolutions.db.default.autoApply=, i.e. either -Dplay.evolutions.db.default.autoApply=true or -Dplay.evolutions.db.default.autoApply=false parameter):

    VAR has type STRING rather than BOOLEAN

  3. Using yes or no as a variable results in:

    contains true, which is an invalid type, it should be a string, number, or a null

  4. Using yes and using a script that transforms yes to true works

Discussion

According the docs Any boolean values; true, false, yes no, need to be enclosed in quotes to ensure they are not converted to True or False by the YML parser:

Environment

Add environment variables. You can use either an array or a dictionary. Any boolean values; true, false, yes no, need to be enclosed in quotes to ensure they are not converted to True or False by the YML parser.

Environment variables with only a key are resolved to their values on the machine Compose is running on, which can be helpful for secret or host-specific values.

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

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

Question

Why is it not allowed?

030
  • 13,383
  • 17
  • 76
  • 178

3 Answers3

32

This come from a design choice of YAML language about booleans

Every unquoted value matching this "regex":

 y|Y|yes|Yes|YES|n|N|no|No|NO
|true|True|TRUE|false|False|FALSE
|on|On|ON|off|Off|OFF

Will be converted to True or False. Note that from YAML 1.2 and onwards it appears that only true and false will be interpreted as boolean values.

This start causing a problem when your code will test an environment value to be yes or no for example taking this script (other examples in the PR discution):

if [ "$SOME_VAR" == "yes" ];
then
  echo "Variable SOME_VAR is activated"
else
  echo "Variable SOME_VAR is NOT activated"
fi

And setting in your compose file

environment:
  SOME_VAR: yes

Will result in SOME_VAR being True when the script run, hence taking the wrong case as it is not equal to yes.

So the choice has been made to disallow boolean to prevent unwanted behaviors hard to debug when you're not aware of the YAML rule.

I see two way to get over the problem:

  1. Using an env_file instead, they are not parsed IIRC and should prevent the conversion.

  2. As you already said, use a wrapper script around your launcher to define the value instead before launching the app, something along the line of this should do:

     AUTOAPPLY=false
     if [ "$SOME_VAR" == "true" ]
     then
         AUTOAPPLY=true
     fi
    

    ./target/universal/stage/bin/APPNAME -Dplay.evolutions.db.default.autoApply=$AUTOAPPLY

Tensibai
  • 11,416
  • 2
  • 37
  • 63
11

That's YAML. It interprets true as a boolean. Envars must be strings, hence the requirement to make the type explicit via quotes.

Test this out with https://www.json2yaml.com/

Assaf Lavie
  • 1,251
  • 11
  • 17
4

double quotes worked for me. Example:

environment:
  MY_VAR: "true"