Configuring Containers Without Rebuilding Images
Hardcoding configuration into an image (like database URLs or API keys) forces a rebuild for every environment change. Environment variables let the same image run correctly in development, staging, and production by injecting configuration at container start time.
Cricket analogy: Printing a fixed pitch report onto a team's kit bag would force reprinting the bag for every new ground; instead teams read the day's pitch conditions fresh at the toss, just as apps read environment variables at container start rather than baking config into the image.
Setting Variables with -e
The -e flag passes individual key-value pairs to docker run, and the application reads them via its language's standard environment variable APIs.
Cricket analogy: Handing the umpire a scorecard with individual notes for each rule variation of this specific match (powerplay overs, DRS reviews available) is like passing individual -e key-value flags to docker run, each one a distinct setting the umpire reads directly.
docker run -d --name api \
-e NODE_ENV=production \
-e DB_HOST=db \
-e DB_PORT=5432 \
-e LOG_LEVEL=info \
myapi:1.0
# Pass through a variable already set in your shell
export API_KEY=secret123
docker run -e API_KEY myapi:1.0Using an Env File
For many variables, --env-file loads key-value pairs from a file, keeping the docker run command short and configuration reviewable in version control (excluding secrets).
Cricket analogy: Instead of announcing every fielding position individually before the over, a captain hands the umpire a single pre-written field-placement card to read from; --env-file similarly loads many key-value pairs from one file, keeping the docker run command short.
# .env.production
NODE_ENV=production
DB_HOST=db
DB_PORT=5432
LOG_LEVEL=infodocker run -d --name api --env-file .env.production myapi:1.0Never commit files containing real secrets (passwords, API keys) to version control. Use a secrets manager or a .gitignore'd .env file for local development, and injected CI/CD secrets for production.
Setting Defaults in the Dockerfile
The ENV instruction in a Dockerfile sets a default value baked into the image, which can still be overridden at runtime with -e.
Cricket analogy: A ground's default pitch curator settings (grass length, roller pressure) are pre-set before the season but can still be overridden by the home team's specific request on match day, just as a Dockerfile's ENV sets a default that -e can override at runtime.
FROM node:20-slim
ENV NODE_ENV=production \
PORT=3000
WORKDIR /app
COPY . .
RUN npm ci --omit=dev
EXPOSE 3000
CMD ["node", "server.js"]Inspecting Configured Variables
You can verify what environment variables a running container actually has, which is useful for debugging misconfiguration.
Cricket analogy: Before a match, the umpire can walk out and physically check exactly what field settings and equipment the fielding side actually has in play, not just what was planned; this mirrors inspecting a running container's actual environment variables to debug misconfiguration.
docker exec api env
docker inspect -f '{{range .Config.Env}}{{println .}}{{end}}' api- -e KEY=VALUE sets an individual environment variable at container start
- --env-file loads many variables from a file, keeping commands clean
- Dockerfile ENV sets a baked-in default that -e at runtime can override
- -e KEY (no value) passes through a variable already exported in your shell
- Never commit real secrets in .env files or Dockerfiles; use secret managers or CI/CD-injected secrets
- docker exec <container> env lets you verify the actual environment inside a running container
Practice what you learned
1. What is the main benefit of using environment variables instead of hardcoding config into an image?
2. Which flag loads multiple key-value pairs from a file into a container's environment?
3. In a Dockerfile, which instruction sets a default environment variable that can still be overridden at runtime?
4. What does `docker run -e API_KEY myapi:1.0` do if API_KEY is already exported in the host shell?
5. Why is it discouraged to commit a .env file containing real secrets to version control?
Was this page helpful?
You May Also Like
Volumes and Persistent Storage
Learn how Docker volumes and bind mounts persist and share data beyond a container's lifecycle, and when to use each option.
Docker Compose Basics
Learn how Docker Compose defines and runs multi-container applications from a single YAML file, replacing long manual docker run commands.
ConfigMaps and Secrets
Learn how to externalize configuration and sensitive data from container images using ConfigMaps and Secrets in Kubernetes.
Docker Security Basics
Defensive practices for hardening container images and runtime, including non-root users, minimal base images, vulnerability scanning, and dropped capabilities.
Related Reading
Related Study Notes in DevOps
Browse all study notesNginx Study Notes
DevOps · 30 topics
DevOpsAnsible Study Notes
DevOps · 30 topics
DevOpsAdvanced Kubernetes Study Notes
Kubernetes · 30 topics
DevOpsAdvanced Bash Scripting Study Notes
Bash · 30 topics
DevOpsApache Kafka Study Notes
Kafka · 30 topics
DevOpsCI/CD Tools & Pipelines Study Notes
YAML · 37 topics