Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a JSON file as environment variable in Docker

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.

like image 965
Spaniard89 Avatar asked Feb 24 '17 16:02

Spaniard89


People also ask

How do I pass an environment variable in Docker run?

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.

Can you use environment variables in JSON?

You have to wrap the environment variable of choice into another set of quotes in order for it to be valid JSON.

Can you use an ENV file in a Dockerfile?

You can use docker run --env-file [path-toenv-file] to provide the environment variables to the container from a . env file.

How do I set an environment variable on an existing container?

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.


1 Answers

Updated answer

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)\" ..."

Original answer

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)"
like image 184
helmbert Avatar answered Oct 07 '22 16:10

helmbert