Docker Environment Variables Example
1. Introduction
In this post, we will discuss different ways to pass and set environment variables into a Docker container. Typically, when a new container is created Docker assigns it a few environment variables by default like so:
$ docker run alpine:latest env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=de2c993a62fb HOME=/root
Let us now explore what options do we have to inject our custom environment variables into a Docker container.
2. Set environment variables within the container
Lets first look at the simplest way possible to set environment variables – open a terminal into the container and set environmnt an variable.
For this lets first create a very simple container based on alpine:linux and one that spawns an infinite-loop.
$ vi Dockerfile FROM alpine:latest MAINTAINER Hariharan Narayanan COPY ./infinite-loop.sh / CMD ["sh", "/infinite-loop.sh"] $ $ vi infinite_loop.sh while (true); do echo hi; done $ $ docker build --label=infinite_loop --tag=infinite_loop_1:latest . Sending build context to Docker daemon 3.072 kB Step 1 : FROM alpine:latest ---> baa5d63471ea Step 2 : MAINTAINER Hariharan Narayanan ---> Running in 52b7476a78de ---> 430c5ef6db0b Removing intermediate container 52b7476a78de Step 3 : COPY ./infinite-loop.sh / ---> 3ad24e361423 Removing intermediate container 25905f482a3d Step 4 : CMD sh /infinite-loop.sh ---> Running in 1a7cf984561b ---> 2e386a31727b Removing intermediate container 1a7cf984561b Step 5 : LABEL "infinite_loop" "" ---> Running in 37ba69ab8515 ---> 6f683b1c8437 Removing intermediate container 37ba69ab8515 Successfully built 6f683b1c8437 $ $ docker run --detach infinite_loop_1:latest 59d4009b9cd1ec274d03799f9913622599fcbdf76eaef32c5f545088bb84c544
Now, open a shell into the container and set an environment variable called example_env_var
and set to value xyz
.
$ docker exec -it 59d4009b9cd1ec274d03799f9913622599fcbdf76eaef32c5f545088bb84c544 /bin/sh / # export example_env_var=xyz / # env HOSTNAME=59d4009b9cd1 SHLVL=1 HOME=/root example_env_var=xyz PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PWD=/
The command env
verifies that the environment variable example_env_var
is set to value xyz
.
Now open another session into the same container and check the environment variables set again.
$ docker exec -it 59d4009b9cd1ec274d03799f9913622599fcbdf76eaef32c5f545088bb84c544 /bin/sh / # env HOSTNAME=59d4009b9cd1 SHLVL=1 HOME=/root PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PWD=/ / #
As can be seen, the new session does not have the environment variable example_env_var
set. Lets explore if we can set environment variables in such a way that they are visible in all containers derived from this Docker image.
3. Set environment variables from the Docker CLI
The environment variable example_env_var=xyz
was set above within a container session. This setting was not persistent across container sessions however. Docker engine CLI provides the --env
option in docker run
command to set environment variables. Lets try a few examples now.
3.1 Set a single environment variable
The environment variable example_env_var=xyz
can be set in the docker run
command using the --env
option like so.
$ docker run --detach --env example_env_var=xyz infinite_loop_1:latest 140311b1ab884142bbf055c16899b25b613d5810f99dd712710eb0da818b3c5b $ docker exec -it 140311b1ab884142bbf055c16899b25b613d5810f99dd712710eb0da818b3c5b env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=140311b1ab88 example_env_var=xyz HOME=/root
Now let’s check from another terminal if the environment variable is still set
$ docker exec -it 140311b1ab884142bbf055c16899b25b613d5810f99dd712710eb0da818b3c5b env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=140311b1ab88 example_env_var=xyz HOME=/root
So this time the environment variable is set across sessions. Containers and images deriving from this image also will get these variables.
3.2 Set multiple environment variables
Multiple environment variables can be set by using multiple --env
options.
$ docker run --detach --env example_env_var=xyz --env example_env_var_2=abc --env example_env_var_3=1 --env example_env_var_4=true infinite_loop_1:latest $ $ docker exec -it be8120b6a7eeb90a0966f6d1b4bb7c07583ddd1dd2618033f9173da916db6e4f env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=be8120b6a7ee example_env_var=xyz example_env_var_2=abc example_env_var_3=1 example_env_var_4=true HOME=/root
This can become cumbersome when there are many environment variables to be set. This can be eased out by moving environment variables into a separate file, like this…
$ vi settings.env example_env_var=xyz example_env_var_2=abc example_env_var_3=1 example_env_var_4=true $ $ docker run --detach --env-file=settings.env infinite_loop_1:latest 10ede841b2d3594a6aa5d12efe33144e8d6ee5b9ad10763dfaa97991c63a3162 $ $ docker exec -it 10ede841b2d3594a6aa5d12efe33144e8d6ee5b9ad10763dfaa97991c63a3162 env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=10ede841b2d3 example_env_var=xyz example_env_var_2=abc example_env_var_3=1 example_env_var_4=true HOME=/root
We saw how to set environment variables from the docker run
command by using the --env
and --enf-file
options. Let us try doing the same without using these options but using instead the options provided in the Dockerfile itself.
4. Set environment variables from Dockerfile
Docker engine provides the instruction ENV
to set environment variables in the Dockerfile.
Lets redo the actions done above and introduce the same environment variables in the Dockerfile using the ENV ionstruction like so.
$ vi Dockerfile FROM alpine:latest MAINTAINER Hariharan Narayanan ENV example_env_var=xyz ENV example_env_var_2=abc ENV example_env_var_3=1 ENV example_env_var_4=true COPY ./infinite-loop.sh / CMD ["sh", "/infinite-loop.sh"] $ $ docker build --label=infinite_loop --tag=infinite_loop_3:latest . Sending build context to Docker daemon 4.096 kB Step 1 : FROM alpine:latest ---> baa5d63471ea Step 2 : MAINTAINER Hariharan Narayanan ---> Using cache ---> 430c5ef6db0b Step 3 : ENV example_env_var xyz ---> Running in de2ddabf92ed ---> 679eede67284 Removing intermediate container de2ddabf92ed Step 4 : ENV example_env_var_2 abc ---> Running in f9bda788b180 ---> 1e6a619df135 Removing intermediate container f9bda788b180 Step 5 : ENV example_env_var_3 1 ---> Running in 6b90bf849305 ---> 9ccfd0dff3dc Removing intermediate container 6b90bf849305 Step 6 : ENV example_env_var_4 true ---> Running in b22534b4619b ---> 02ba8f83be20 Removing intermediate container b22534b4619b Step 7 : COPY ./infinite-loop.sh / ---> 42d3f60549f0 Removing intermediate container 7cd3d47df6c4 Step 8 : CMD sh /infinite-loop.sh ---> Running in c2991b057887 ---> cdd321499fd2 Removing intermediate container c2991b057887 Step 9 : LABEL "infinite_loop" "" ---> Running in d643b9354e8c ---> 87b2ae39b41e Removing intermediate container d643b9354e8c Successfully built 87b2ae39b41e $ $ docker exec -it 09082da1a35470155d95b49125394a5505c6c1112d3a4b12f57dcbdbff93d057 env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=09082da1a354 example_env_var=xyz example_env_var_2=abc example_env_var_3=1 example_env_var_4=true HOME=/root
Multiple ENV values can also be combined into a single instruction like below. This saves multiple layers in the resulting Docker image.
$ vi Dockerfile FROM alpine:latest MAINTAINER Hariharan Narayanan ENV example_env_var=xyz \ example_env_var_2=abc \ example_env_var_3=1 \ example_env_var_4=true COPY ./infinite-loop.sh / CMD ["sh", "/infinite-loop.sh"]
5. Summary
In this post, we saw different forms of injecting environment variables into Docker containers. Docker provides the --env
option to inject environment variables through the docker run
command. Multiple environment variables are injected through multiple --env
options one for each variable. Environment variables can also be defined in a separate file and injected through the docker run --env-file
call. In a Dockerfile, the ENV
instruction is used to provide multiple environment variables. Each ENV
call creates a new layer in the Docker image and so multiple environment variable definitions can be combined into one ENV call too.