Skip to content

1.05 Docker Environment Variables

Overview

Environment variables allow you to pass runtime configuration into containers without modifying application code. They decouple config from code β€” a core principle of the 12-Factor App.

Abstract

Instead of hardcoding values like colors, ports, or database URLs inside your application, you inject them as environment variables at runtime. This makes the same Docker image reusable across dev, staging, and production by simply changing the environment β€” not the code.


Why It Matters in Production

Hardcoded config values force code changes for every environment. Environment variables let you:

  • Run the same image across multiple environments with different settings
  • Rotate secrets and config without rebuilding images
  • Follow security best practices by keeping secrets out of source control

Key Concepts

Concept Description
os.environ.get('VAR') Python method to read an env var at runtime
-e flag docker run option to inject an env var into the container
docker inspect Command to view all env vars set on a running container
Config.Env Section in docker inspect output listing all container env vars

Common Use Cases

  • Setting a UI theme or color without redeploying code
  • Passing database connection strings (host, port, credentials)
  • Configuring feature flags per environment
  • Setting log levels (DEBUG in dev, ERROR in prod)
  • Injecting API keys or tokens at container startup

Example Configuration or Commands

Application Code β€” Reading an Env Var

import os
from flask import Flask

app = Flask(__name__)

color = os.environ.get('APP_COLOR')

@app.route("/")
def main():
    print(color)
    return render_template('hello.html', color=color)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080)

Setting an Env Var Before Running Locally

# Export the variable in your shell, then run the app
export APP_COLOR=blue; python app.py

Passing Env Vars with docker run

# Single env var with -e flag
docker run -e APP_COLOR=blue simple-webapp-color

# Deploy the same image with a different color
docker run -e APP_COLOR=green simple-webapp-color

# Another instance with a different value
docker run -e APP_COLOR=pink simple-webapp-color

Inspecting Env Vars on a Running Container

# View full container config including all environment variables
docker inspect blissful_hopper

The Config.Env section of the output will show all set variables:

"Config": {
    "Env": [
        "APP_COLOR=blue",
        "LANG=C.UTF-8",
        "GPG_KEY=0D96DF4D4110E5C43FBFB17F2D347EA6AA65421D",
        "PYTHON_VERSION=3.6.6",
        "PYTHON_PIP_VERSION=18.1"
    ]
}

Using --env-file for Multiple Variables

# Pass multiple env vars from a file (preferred for many vars)
docker run --env-file ./app.env simple-webapp-color
# app.env
APP_COLOR=blue
APP_PORT=8080
LOG_LEVEL=info

Best Practices

Best Practices

  • Externalize all environment-specific config (ports, hostnames, feature flags, colors) as env vars β€” never hardcode them
  • Use --env-file to manage multiple variables cleanly rather than chaining -e flags
  • Provide sensible defaults in application code with os.environ.get('VAR', 'default') for non-sensitive values
  • Document all required env vars in your project's README or a .env.example file
  • Use docker inspect <container> to audit what variables are active in any running container

Security Best Practices

Security

  • Never pass secrets (passwords, API keys, tokens) via -e on the command line β€” they appear in shell history and docker inspect output in plain text
  • Use Docker Secrets, Vault, AWS Secrets Manager, or Kubernetes Secrets for sensitive values in production
  • Do not commit .env files containing real credentials to source control β€” add them to .gitignore
  • Rotate credentials regularly; injecting them as env vars (rather than baking into images) makes rotation straightforward
  • Prefer --env-file over inline -e flags in scripts β€” the file can have tighter filesystem permissions

Do and Don't

βœ… Do ❌ Don't
Use -e APP_COLOR=blue to pass config at runtime Hardcode config values inside application source code
Use --env-file for multiple env vars Chain many -e flags on a single long command
Store secrets in a secrets manager Pass passwords via -e on the CLI
Add .env to .gitignore Commit real credentials in .env files
Use docker inspect to audit running container config Assume env vars are set without verifying
Provide defaults in code for optional vars Let the app crash silently when an env var is missing

Common Mistakes

Common Mistakes

  • Forgetting to export the variable locally (export APP_COLOR=blue) before running β€” APP_COLOR=blue python app.py only sets it for that single command
  • Passing the -e flag after the image name β€” flags must come before the image name in docker run
  • Expecting env vars set on the host to automatically propagate into the container β€” they don't unless explicitly passed with -e VAR or -e VAR=value
  • Storing sensitive env vars in a Dockerfile using ENV β€” they get baked into image layers and are visible in docker history

Troubleshooting

Check which env vars are active inside a container

# Option 1: docker inspect (from the host)
docker inspect <container_name_or_id>

# Option 2: exec into the container and print env
docker exec -it <container_name> env

Confirm the app is reading the variable

# Exec into the container and check the specific variable
docker exec -it <container_name> printenv APP_COLOR

Variable is set but app ignores it

  • Confirm the app reads it at startup, not at import time before the variable is injected
  • Check for typos β€” env var names are case-sensitive (APP_COLOR β‰  app_color)

Quick Recap

  • Environment variables decouple config from code β€” the same image runs anywhere with different settings
  • Use docker run -e KEY=VALUE image to inject env vars at container startup
  • Deploy multiple containers from the same image with different env vars using separate docker run commands
  • Use docker inspect <container> β†’ Config.Env to view all env vars on a running container
  • Never hardcode secrets in images; use a secrets manager or vault in production

Interview / Revision Notes

  • Q: How do you pass an environment variable to a Docker container? Use docker run -e KEY=VALUE image or docker run --env-file file.env image

  • Q: How do you check which env vars are set on a running container? docker inspect <container> β€” look under Config.Env

  • Q: Why should secrets not be passed via -e on the CLI? They are stored in shell history and visible in plain text via docker inspect

  • Q: What is the advantage of using --env-file over multiple -e flags? Cleaner commands, easier management, and the file can have restricted permissions

  • Q: Does setting an env var on the host automatically pass it into the container? No β€” it must be explicitly forwarded with -e VARNAME or -e VARNAME=value