263

What's the simplest way to get an environment variable from a docker container that has not been declared in the Dockerfile?

For instance, an environment variable that has been set through some docker exec container /bin/bash session?

I can do docker exec container env | grep ENV_VAR, but I would prefer something that just returns the value.

I've tried using docker exec container echo "$ENV_VAR", but the substitution seems to happen outside of the container, so I don't get the env var from the container, but rather the env var from my own computer.

Thanks.

3
  • Is there a reason why would like not to use env and grep? Commented Dec 2, 2015 at 20:05
  • 1
    I just need the value. If I understand correctly, I'd need to parse the output of the grep call, and I'd rather avoid that. Commented Dec 2, 2015 at 20:12
  • I had thought variable that was set in an exec session does not affect the primary process or subsequent exec sessions? Commented Dec 3, 2015 at 3:02

12 Answers 12

312

To view all env variables:

docker exec container env

To get one:

docker exec container env | grep VARIABLE | cut -d'=' -f2
Sign up to request clarification or add additional context in comments.

6 Comments

My question says that I'd prefer not to go that route. Also, follow-up question: docker exec container env and docker exec -it container /bin/bash and then env spit out different things. Why?
Ah... might be the specific way I'm building the docker image that makes this the case...
Hm, a lot harder now. Try docker inspect container.
docker inspect container seems to have the same limitation. If I create an environment variable after I run the container, it doesn't appear in a call to docker inspect (in the env section).
Say @aisbaa if VARIABLE is a password generated from openssl rand -base64 14 or any other case scenario where VARIABLE contains an equals sign then cut -d'=' -f2 would leave out everything after the 2nd match, however, cut -d '=' -f 2- would only match the first delimiter and print everything after that.
|
212

The proper way to run echo "$ENV_VAR" inside the container so that the variable substitution happens in the container is:

docker exec <container_id> bash -c 'echo "$ENV_VAR"'

6 Comments

NOTICE that all these answers depend on some shell. I'm not able to get env variables with an executable and a scratch base image.
docker run --rm -it CONTAINER bash -c 'echo "$MY_ENV_VAR"'
I am getting error "Error: No such container: container". I am executing command after login through SSH.
@kunwarnitesh: You need to replace "container" with the name of the container you want to operate on.
why does docker exec <container_id> echo $ENV_VAR not work and we have to call bash?
|
122

You can use printenv VARIABLE instead of /bin/bash -c 'echo $VARIABLE. It's much simpler and it does not perform substitution:

docker exec container printenv VARIABLE

4 Comments

This should be the final answer
or just printenv to print all variables.
This works even for kubernetes: kubectl exec pod-name printenv MY_VARIABLE.
container here is the container name or id
109

The downside of using docker exec is that it requires a running container, so docker inspect -f might be handy if you're unsure a container is running.

Example #1. Output a list of space-separated environment variables in the specified container:

docker inspect -f \
   '{{range $index, $value := .Config.Env}}{{$value}} {{end}}' container_name

the output will look like this:

ENV_VAR1=value1 ENV_VAR2=value2 ENV_VAR3=value3

Example #2. Output each env var on new line and grep the needed items, for example, the mysql container's settings could be retrieved like this:

docker inspect -f \
    '{{range $index, $value := .Config.Env}}{{println $value}}{{end}}' \
    container_name | grep MYSQL_

will output:

MYSQL_PASSWORD=secret
MYSQL_ROOT_PASSWORD=supersecret
MYSQL_USER=demo
MYSQL_DATABASE=demodb
MYSQL_MAJOR=5.5
MYSQL_VERSION=5.5.52

Example #3. Let's modify the example above to get a bash friendly output which can be directly used in your scripts:

docker inspect -f \
   '{{range $index, $value := .Config.Env}}export {{$value}}{{println}}{{end}}' \
   container_name | grep MYSQL

will output:

export MYSQL_PASSWORD=secret
export MYSQL_ROOT_PASSWORD=supersecret
export MYSQL_USER=demo
export MYSQL_DATABASE=demodb
export MYSQL_MAJOR=5.5
export MYSQL_VERSION=5.5.52

If you want to dive deeper, then go to Go’s text/template package documentation with all the details of the format.

7 Comments

that's the best answer. I think is should be the answer on a separate question (when container is down)
This is the only answer that worked for me. docker exec always said my container is not know.
This is the best answer because every other solution uses docker exec which depends on having whatever command you exec to be supported by the container. This answer on the other hand works for any container since it only relies on the container metadata.
could you explain why $index? I read golang.org/pkg/text/template but still don't understand why using two variables when only one is used.
@Stefan, full example will look like this: {{range $key, $value := .State}}{{$key}}="{{$value}}"{{println}}{{end}}.
|
24

Since we are dealing with JSON and unlike the accepted answer, we don't need to exec the container.

docker inspect <NAME|ID> | jq '.[] | .Config.Env'

Output sample

[
  "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
  "NGINX_VERSION=1.19.4",
  "NJS_VERSION=0.4.4",
  "PKG_RELEASE=1~buster"
]

To retrieve a specific variable

docker inspect <NAME|ID> | jq -r '.[].Config.Env[]|select(match("^<VAR_NAME>"))|.[index("=")+1:]'

See jq

2 Comments

This is good but it doesn't solve the problem of getting a specific environment variable.
I used this jq to extract a specific environment variable: docker inspect <CONTAINER> | jq -r '.[].Config.Env[]|select(match("^<VAR>"))|.[index("=")+1:]'
11

None of the above answers show you how to extract a variable from a non-running container (if you use the echo approach with run, you won't get any output).

Simply run with printenv, like so:

docker run --rm <container> printenv <MY_VAR>

(Note that docker-compose instead of docker works too)

2 Comments

very straightforward! I settled for this approach.
or just printenv to print all variables.
5

If by any chance you use VSCode and has installed the docker extension, just right+click on the docker you want to check (within the docker extension), click on Inspect, and there search for env, you will find all your env variables values

Comments

1

We can modify entrypoint of a non-running container with the docker run command.

Example show PATH environment variable:

  1. using bash and echo: This answer claims that echo will not produce any output, which is incorrect.

    docker run --rm --entrypoint bash <container> -c 'echo "$PATH"'
    
  2. using printenv

    docker run --rm --entrypoint printenv <container> PATH
    

Comments

1

There is a misconception in the question, that causes confusion:

you cannot access a "running session", so no bash session can change anything.

docker exec -ti container /bin/bash

starts a new console process in the container, so if you do export VAR=VALUE this will go away as soon as you leave the shell, and it won't exist anymore.

Perhaps a good example:

# assuming TESTVAR did not existed previously this is empty 
docker exec container env | grep TESTVAR

# -> TESTVAR=a new value!
docker exec container /bin/bash -c 'TESTVAR="a new value!" env' | grep TESTVAR

# again empty
docker exec container env | grep TESTVAR

The variables from env come from the Dockerfile or command, docker itself and whatever the entrypoint sets.

The other answers here are good. But if you really need to get the environmental properties used when starting a program, then you can inspect the /proc/pid/environ contents in the container, where pid is the container process id of the running comand.

# environmental props 
docker exec container cat /proc/pid/environ | tr '\0' '\n'

# you can check this is the correct pid by checking the ran command
docker exec container cat /proc/pid/cmdline | tr '\0' ' '

Comments

0

@aisbaa's answer works if you don't care when the environment variable was declared. If you want the environment variable, even if it has been declared inside of an exec /bin/bash session, use something like:

IFS="=" read -a out <<< $(docker exec container /bin/bash -c "env | grep ENV_VAR" 2>&1)

It's not very pretty, but it gets the job done.

To then get the value, use:

echo ${out[1]}

1 Comment

See jwodder's answer.
0

This command inspects docker stack processes' environment in the host :

pidof   dockerd containerd containerd-shim | tr ' ' '\n' \
      | xargs -L1 -I{} -- sudo xargs -a '/proc/{}/environ' -L1 -0

Comments

0

The first way we use to find the ENV variables is docker inspect <container name>

The second way is docker exec <4 alphanumeric letter of CONTAINER id> bash -c 'echo "$ENV_VAR"'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.