Why is one not allowed to use a Boolean in a docker-compose.yml? 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


If true is changed to True the issue persists.
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
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
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?
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:


Using an env_file instead, they are not parsed IIRC and should prevent the conversion.
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