I would like to pass the content of a JSON file as an environment variable during the docker run. The docker run is initialed inside a systemd service file.
I did something like:
export TEMP_CONFIG=$(cat /etc/config.json)
and run docker container as follow:
docker run \
--env SERVICE_NAME=${CONTAINER_NAME} \
--env TEMP_CONFIG \
But when I am inside the docker container and try to echo the variable ${TEMP_CONFIG} It's empty.
root@ip-10-109-7-77:/usr/local/nginx/conf# echo ${TEMP_CONFIG}
root@ip-10-109-7-77:/usr/local/nginx/conf#
is there a way to pass content of a JSON file as environment variable?
BTW:
--env TEMP_CONFIG=$(cat /etc/config.json) \
Doing above throws an exception:
docker: Error parsing reference: "\"conf\"" is not a valid repository/tag.
The content of config.json is:
{
"conf" :
{
"appname" :
{
"dbhost" : "xxxx",
"dbname" : "dbname",
"dbuser" : "user",
"dbpassword" : "xxxxx",
"hostname" : "xxxxxx"
},
"cacheBaseDir" : "/storage/",
"iccprofile" : "/etc/nginx/RGB.V1.0.icc",
"tmpDir" : "/tmp",
"mdb" :
{
"user" : "user",
"password" : "xxxxx",
"rights" : "GlobalAdministrator",
"company" : "somecompany"
}
}
}
Any help is definitely appreciated.
When we launch our Docker container, we can pass environment variables as key-value pairs directly into the command line using the parameter –env (or its short form -e). As can be seen, the Docker container correctly interprets the variable VARIABLE1.
You have to wrap the environment variable of choice into another set of quotes in order for it to be valid JSON.
You can use docker run --env-file [path-toenv-file] to provide the environment variables to the container from a . env file.
Use the -e , --env , and --env-file flags to set simple (non-array) environment variables in the container you're running, or overwrite variables that are defined in the Dockerfile of the image you're running.
You mentioned that you use the docker run
command in a systemd unit file. A systemd ExecStart
options is not started in a shell. Environment variable substitution is supported by name. Also see the documentation on this:
Basic environment variable substitution is supported. Use "
${FOO}
" as part of a word, or as a word of its own, on the command line, in which case it will be replaced by the value of the environment variable including all whitespace it contains, resulting in a single argument.
The doc also says that StartExec
is not executed in a shell:
This syntax is intended to be very similar to shell syntax, but only the meta-characters and expansions described in the following paragraphs are understood. Specifically, redirection using "<", "<<", ">", and ">>", pipes using "|", running programs in the background using "&", and other elements of shell syntax are not supported. [...] Note that shell command lines are not directly supported.
However, you can use ExecStart
to start a shell and then pass a command using the -c
flag (you still need to quote the variable as mentioned in my original answer below):
ExecStart=/bin/bash -c "docker run -e \"TEMP_CONFIG=$(</etc/config.json)\" ..."
Your JSON string contains spaces, and without quoting your shell will interpret everything after the first space as subsequent arguments. So TEMP_CONFIG=$(cat /etc/config.json)
is essentially equivalent to:
--env TEMP_CONFIG={ "conf" : { "...
In this case, the TEMP_CONFIG
environmant variable will have the value {
, and docker run
will assume "conf"
to be the next argument (in this case, the image name).
Solution: Quote your bash variables:
--env "TEMP_CONFIG=$(cat /etc/config.json)"
Also, don't use cat
when you don't have to:
--env "TEMP_CONFIG=$(</etc/config.json)"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With