Passing a JSON file as environment variable in Docker
Asked Answered
A

2

20

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.

Adhere answered 24/2, 2017 at 16:47 Comment(0)
T
15

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)"
Thickening answered 24/2, 2017 at 16:57 Comment(6)
Unfortunately it doesn't work, I am getting the same error as before. BTW, the call is within a systemd service file.Adhere
The systemd part is important! I'll update my answer, but I'd also recommend for you to include this information in your question.Thickening
Thanks a lot for the updated answer, I use ExecStart=/bin/bash -c in my sytemd service file, and I also tried calling docker run with "TEMP_CONFIG=$(</etc/config.json)" as an argument, still the environment variable TEMP_CONFIG inside the container is empty. Just out of curiosity, in your updated answer there's backslash at both beginning and end: \"TEMP_CONFIG=$(</etc/config.json)\" what do they mean?Adhere
I just tried your solution out and worked as charm, now I understand why there's a backslash in front, it is to escape the quotes. That was a very naive question, in the comment before, apologise for that :) I tried it before without the backslash.Adhere
Since JSON uses double quotes for values, wrap the whole thing in single quotes for the shell.Aframe
Base64 encode the JSON payload outside Docker, pass the shell-safe Base64 string in as an environment variable, and decode the message once inside Docker.Mustang
P
0

If you want to do it on windows this working for me: you still need to quote the variable as mentioned below. See example here

Portiere answered 9/5 at 7:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.