LearnAI ToolsCareerPractice BuildsPlayDevelopmentContact
Lesson 912 min read

Environment Variables and Configuration

Configure containers without rebuilding them using -e and --env-file, understand ENV and ARG in a Dockerfile, and keep passwords out of your images.

On this page 10 sections

Introduction

The same image should run on your laptop, in testing and in production — only the configuration changes: database addresses, feature flags, API keys. The standard way to pass that configuration to a container is environment variables.

What You Will Learn
  • How to set environment variables with -e and --env-file.
  • The difference between ENV and ARG in a Dockerfile.
  • How images such as PostgreSQL use required variables.
  • Why secrets must never be written into a Dockerfile.

Setting Variables with -e

Priya’s Quotes API reads its greeting from the GREETING variable, with a default (look at os.environ.get in app.py from lesson 5). Without the variable, the API answers “Hello from Docker!”. With -e, the same image says something else — no rebuild needed:

docker run -d --name api -p 5000:5000 -e GREETING="Hello from Priya's laptop" quotes-api
curl http://localhost:5000/

The JSON response now contains the new message. Repeat -e for each variable: -e APP_ENV=production -e LOG_LEVEL=debug. Writing -e GREETING without a value copies the variable from your own shell.

Env Files: --env-file

With many variables, put them in a file — one NAME=value per line, no quotes needed:

.env
GREETING=Hello from the env file!
APP_ENV=production
docker run --rm --env-file .env quotes-api env

env (replacing CMD) prints every variable in the container, including GREETING and APP_ENV from the file, and others such as PATH and PYTHON_VERSION that come from the python base image. Keep env files with real secrets out of Git (.gitignore) and out of images (.dockerignore).

ENV and ARG in a Dockerfile

ENVARG
Available during buildYesYes
Available in running containersYesNo
Set or overridden withdocker run -edocker build --build-arg
Typical useDefaults for the app (PYTHONUNBUFFERED=1, PORT=5000)Build options (versions, build flags)

They are often combined to bake a build-time value into the image:

Dockerfile
FROM alpine
ARG APP_VERSION=1.0.0
ENV APP_VERSION=$APP_VERSION
CMD ["sh", "-c", "echo Running version $APP_VERSION"]
docker build -t versioned .
docker run --rm versioned # Running version 1.0.0
docker build --build-arg APP_VERSION=2.1.0 -t versioned:2.1.0 .
docker run --rm versioned:2.1.0 # Running version 2.1.0

Required Variables

Many official images are configured entirely through variables. PostgreSQL refuses to start without a password:

docker run --rm postgres:18-alpine

It exits with an error explaining that the database is uninitialised and you must specify POSTGRES_PASSWORD. The image documentation on Docker Hub lists every supported variable — for PostgreSQL also POSTGRES_USER and POSTGRES_DB:

docker run -d --name db -e POSTGRES_USER=app -e POSTGRES_PASSWORD=change-me -e POSTGRES_DB=shop postgres:18-alpine

Keeping Secrets Safe

Environment variables are not hidden. Anyone who can run docker commands on the machine can read them:

docker inspect api --format "{{range .Config.Env}}{{println .}}{{end}}"

Worse is a secret written into a Dockerfile with ENV. It becomes part of the image, and anyone who pulls the image can read it — even if a later step tries to remove it:

Dockerfile — never do this
FROM alpine
ENV API_KEY=sk-live-1234567890
docker history leaky # the API_KEY value is listed in plain text
  • Never put passwords, tokens or keys in a Dockerfile or copy .env files into an image.
  • Pass secrets at run time with -e or --env-file, from a file that is not committed to Git.
  • In production, prefer a secrets manager or Docker/Compose secrets, which mount secrets as files instead of variables.
  • For secrets needed only during the build (such as a private package token), use BuildKit build secrets: RUN --mount=type=secret.
Mini Challenge · Spot the Problem

Which way of giving a container a database password is unsafe?

Choose one answer

Common Mistakes

Avoid These Mistakes
  • Baking secrets into images with ENV, or copying .env files in with COPY . .
  • Rebuilding an image just to change configuration — use variables instead.
  • Putting quotes in env files expecting them to be removed; with --env-file they become part of the value.
  • Expecting ARG values to exist in the running container — only ENV does.

Frequently Asked Questions

You need to recreate it: remove the container and run it again with the new value. Variables are fixed when a container is created.

A widely used set of guidelines for building cloud apps. One rule is to store configuration in the environment, which is exactly what this lesson does.

Yes — Compose automatically reads a .env file in the project folder and can use its values in compose.yaml. You will see this in the projects.

Key Takeaways

  • Configure containers with -e NAME=value or --env-file file, without rebuilding.
  • ENV sets variables in the image and containers; ARG only exists during the build.
  • Official images such as PostgreSQL are configured through documented variables.
  • Environment variables are visible with docker inspect; ENV values are visible in docker history.
  • Never put secrets in a Dockerfile — supply them at run time or use a secrets mechanism.

Summary

You can now configure containers safely. Next you will stop typing long docker run commands altogether: Docker Compose describes a whole multi-container app in one file.

Next Lesson →

Docker Compose: Multi-Container Apps