Course outline · 0% complete

0/29 lessons0%

Course overview →

ENTRYPOINT, ENV, and ARG

lesson 3-4 · ~11 min · 10/29

The instructions real Dockerfiles add

Open the Dockerfile of almost any serious open-source project and you will meet three instructions lesson 3-1 skipped: ENV, ENTRYPOINT, and ARG. They exist because images need configuration at three different moments: values baked in for every run, a fixed command with swappable arguments, and values that exist only while building. Confusing them produces two classic bugs: config that mysteriously will not change, and "why is my command-line flag being ignored".

ENV sets an environment variable inside the image, available during the rest of the build and in every container started from it:

ENV PYTHONUNBUFFERED=1

Use it for settings that should hold everywhere the image runs (this one makes Python print logs immediately instead of buffering them, so docker logs shows output live). Per-machine config like DATABASE_URL still comes at run time via -e or compose environment: (lesson 5-2), because baking a machine-specific value into the image would break the run-anywhere promise.

ENTRYPOINT vs CMD

Both say what runs when a container starts, and the real rule is about overriding:

  • ENTRYPOINT is the fixed part of the command. Arguments after the image name in docker run do not replace it
  • CMD is the default arguments. Anything after the image name replaces CMD entirely

Docker starts the container with ENTRYPOINT + CMD glued together:

ENTRYPOINT ["python"]
CMD ["server.py"]
  • docker run myapp → runs python server.py
  • docker run myapp worker.py → runs python worker.py

The image now behaves like a command with a default argument. This is why docker run python:3.12 python in lesson 2-1 could swap the command freely (that image relies on CMD), while images built as single-purpose tools use ENTRYPOINT so users can pass just arguments. When only one of the two is set, CMD alone (lesson 3-1's shape) means the whole command is replaceable.

Code exercise · bash

Run this simulation of Docker assembling the start command. The first line is a plain docker run (ENTRYPOINT + default CMD), the second passes an extra argument, which replaces CMD but never touches ENTRYPOINT.

Quiz

An image has ENTRYPOINT ["python"] and CMD ["server.py"]. What does `docker run myapp worker.py` execute inside the container?

ARG: variables that exist only at build time

ARG declares a variable for the build itself, set from the command line:

ARG PY_VERSION=3.12
FROM python:${PY_VERSION}-slim
docker build --build-arg PY_VERSION=3.13 -t myapp:py13 .

One Dockerfile now builds against either Python version, which is exactly how teams test an upgrade before committing to it. The key difference from ENV: an ARG evaporates when the build finishes. It is not present in running containers, so it is also the wrong place for secrets (build args can still be recovered from image metadata, real secret handling arrives in lesson 8-2).

ENVARG
Exists during buildyesyes
Exists in running containeryesno
Set fromDockerfile, -e at run--build-arg at build

Problem

Which Dockerfile instruction declares a variable that exists during the build but is gone in the running container?