TransWikia.com

Why is one not allowed to use a Boolean in a docker-compose.yml?

DevOps Asked on November 7, 2021

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?

2 Answers

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
    

Answered by Tensibai on November 7, 2021

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/

Answered by Assaf Lavie on November 7, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP