Two instructions set variables in a Dockerfile, and they work at
different times. ARG is for build time; ENV is for run time. Mixing
them up is a common source of confusion.
ENV bakes an environment variable into the image, so every container
started from it has that variable set:
ENV APP_PORT=8080
ENV LOG_LEVEL=info
A process inside the container reads APP_PORT and LOG_LEVEL just
like any environment variable. This is how you give an image sensible
defaults. And because they are ordinary environment variables, whoever
runs the container can override them with -e, exactly as in the
environment-variables topic:
docker run -e LOG_LEVEL=debug myapp
ARG defines a variable available only while the image is building. It
does not exist in the running container:
ARG VERSION=1.0
RUN echo "building version $VERSION"
You pass a value at build time with --build-arg:
docker build --build-arg VERSION=2.0 -t myapp:2.0 .
ARG suits things you need only while building - which version to
download, which base variant to pull - and that should not linger in
the final image.
docker build, gone by run time. Set with
--build-arg.-e.A secret should be neither, as a rule - ARG can leak into build
history and ENV is readable with docker inspect. Pass real secrets
in at run time instead.
ENV KEY=value - set a run-time environment variable in the imageARG NAME=default - define a build-time variable, set with
--build-arg