20

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?

  • 4
    Not about DevOps? DevOps Stack Exchange is a question and answer site for software engineers working on automated testing, continuous delivery, service integration and monitoring, and building SDLC infrastructure – 030 Mar 16 '17 at 17:20
  • 1
    @Aurora0001 question updated – 030 Mar 16 '17 at 17:28
14

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.

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
    
9

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/

  • More generally, the quotes won't appear in the value itself because they are YAML formatting. – coderanger Mar 18 '17 at 21:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.