Docker Environment Variables¶
Pass a Single Environment Variable¶
Containers are stateless by design. Configuration is injected at runtime using environment variables rather than baked into the image. The -e flag passes a key-value pair to a container.
graph TD
E1["-e APP_ENV=production"]-->CNT["📦 Container
Environment"]
E2["--env-file .env"]-->CNT
CNT-->VAR["APP_ENV=production
DB_HOST=postgres
LOG_LEVEL=debug"]
style E1 fill:#f3f4f6,stroke:#9ca3af,stroke-width:2px,color:#1f2937
style E2 fill:#f3f4f6,stroke:#9ca3af,stroke-width:2px,color:#1f2937
style CNT fill:#dcfce7,stroke:#22c55e,stroke-width:2px,color:#14532d
style VAR fill:#dbeafe,stroke:#3b82f6,stroke-width:2px,color:#1e3a8a
Run docker run --rm -e APP_ENV=production alpine:3.22 env | grep APP_ENV to start a container, inject the APP_ENV variable, and immediately print it.
docker run --rm -e APP_ENV=production alpine:3.22 env | grep APP_ENV
APP_ENV=production
Observe that APP_ENV=production appears in the container's environment.
Pass Multiple Environment Variables¶
The -e flag can be repeated multiple times to pass several variables in a single docker run command.
Run docker run --rm -e APP_ENV=staging -e DB_HOST=postgres -e LOG_LEVEL=debug alpine:3.22 env | grep -E "APP_ENV|DB_HOST|LOG_LEVEL" to inject three variables at once.
docker run --rm -e APP_ENV=staging -e DB_HOST=postgres -e LOG_LEVEL=debug alpine:3.22 env | grep -E "APP_ENV|DB_HOST|LOG_LEVEL"
APP_ENV=staging
DB_HOST=postgres
LOG_LEVEL=debug
Verify all three appear in the container's environment output.
Use an Environment File¶
Passing many variables with repeated -e flags becomes unwieldy. An env file stores key-value pairs in a file and passes them all at once using --env-file.
Create an env file.
printf "APP_ENV=production\nDB_HOST=postgres\nDB_PORT=5432\nLOG_LEVEL=info\n" > /workspace/app.env
Verify its contents with cat /workspace/app.env.
cat /workspace/app.env
APP_ENV=production
DB_HOST=postgres
DB_PORT=5432
LOG_LEVEL=info
Launch a container using the file.
docker run --rm --env-file /workspace/app.env alpine:3.22 env | grep -E "APP_ENV|DB_HOST|DB_PORT|LOG_LEVEL"
APP_ENV=production
DB_HOST=postgres
DB_PORT=5432
LOG_LEVEL=info
Inspect Environment Variables Inside a Running Container¶
docker inspect lets you read a container's environment variables without executing a shell session inside it. This is useful for auditing running containers.
Start a background container.
docker run -d --name myapp -e APP_VERSION=2.1 -e REGION=us-east alpine:3.22 sleep infinity
d3e4f5g6h7i8j9k0l1m2n3o4p5q6r7s8t9u0v1w2x3y4z5a6b7c8d9e0f1g2h3i4
First, view the full JSON configuration of the container by running docker inspect myapp.
docker inspect myapp
[
{
"Id": "d3e4f5g6h7i8j9k0l1m2n3o4p5q6r7s8t9u0v1w2x3y4z5a6b7c8d9e0f1g2h3i4",
"Created": "2023-11-01T12:08:00.000000000Z",
"Path": "sleep",
"Args": [
"infinity"
],
"State": {
"Status": "running",
"Running": true,
...
Notice how overwhelming the output is! To extract just the environment variables cleanly, we can use a Go template format. Inspect only its environment.
docker inspect myapp --format '{{range .Config.Env}}{{println .}}{{end}}'
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
APP_VERSION=2.1
REGION=us-east
Override Variables at Runtime¶
Environment variables in a Dockerfile (set with ENV) provide defaults. They can always be overridden at runtime using -e — the runtime value always wins.
This means images can ship sensible defaults while operators inject environment-specific values at deploy time without rebuilding the image.
First, view the default value of the HOME variable built into the Alpine image.
docker run --rm alpine:3.22 env | grep HOME
HOME=/root
Notice that it defaults to /root. Now, override it at runtime.
docker run --rm -e HOME=/override alpine:3.22 env | grep HOME
HOME=/override
Observe how the new runtime value completely replaces the built-in default!
🧠 Quick Quiz¶
Which flag is used to pass a single environment variable to a container at runtime?
How do you pass multiple environment variables from a file into a container?
What happens if you use -e MY_VAR without specifying a value (e.g., -e MY_VAR alone)?
Practice Live in Your Browser
Don't just read about Docker commands—execute them in real time! Launch a fully-configured, secure Docker sandbox directly in your browser with automated task validation ready for you.
📬 DevopsPilot Weekly — Learn DevOps, Cloud & Gen AI the simple way.
👉 Subscribe here