patternMajor
Why is one not allowed to use a Boolean in a docker-compose.yml?
Viewed 0 times
whyallowedbooleandockeronecomposeymlusenot
Problem
Defining a boolean in a docker-compose.yml file:
and running
Attempts to solve the issue
-
Using
VAR has type STRING rather than BOOLEAN
-
Using
contains true, which is an invalid type, it should be a string, number, or a null
-
Using
Discussion
According the docs
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.
Question
Why is it not allowed?
environment:
SOME_VAR: trueand running
docker up results in:contains true, which is an invalid type, it should be a string, number, or a nullAttempts 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 worksDiscussion
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_SECRETQuestion
Why is it not allowed?
Solution
This come from a design choice of YAML language about booleans
Every unquoted value matching this "regex":
Will be converted to
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):
And setting in your compose file
Will result in
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
-
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:
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|OFFWill 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"
fiAnd setting in your compose file
environment:
SOME_VAR: yesWill 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=$AUTOAPPLYCode Snippets
y|Y|yes|Yes|YES|n|N|no|No|NO
|true|True|TRUE|false|False|FALSE
|on|On|ON|off|Off|OFFif [ "$SOME_VAR" == "yes" ];
then
echo "Variable SOME_VAR is activated"
else
echo "Variable SOME_VAR is NOT activated"
fienvironment:
SOME_VAR: yesAUTOAPPLY=false
if [ "$SOME_VAR" == "true" ]
then
AUTOAPPLY=true
fi
./target/universal/stage/bin/APPNAME -Dplay.evolutions.db.default.autoApply=$AUTOAPPLYContext
StackExchange DevOps Q#537, answer score: 31
Revisions (0)
No revisions yet.