Skip to content

Dockerfile — ARGS ENV LABEL


You’ve already seen Dockerfile instructions that build the image and tell the container what to run. ARG, ENV, and LABEL are different — they don’t run anything.

Instead, they let you attach information to the build and the image.

The tricky part is that all three look like simple KEY=value declarations:

ARG VERSION=1.0
ENV APP_ENV=production
LABEL maintainer="[email protected]"

But they answer three very different questions:

  • ARG — What value do I need while building the image?
  • ENV — What environment variable should exist in the image or container?
  • LABEL — What metadata should be attached to the image?

They’re not alternatives to each other. They’re tools for different jobs.

What ARG Does?

ARG defines a build-time variable.

For example:

ARG NODE_VERSION=22
FROM node:${NODE_VERSION}

You can override it when building:

docker build --build-arg NODE_VERSION=20 .

The important word here is build.

Once the image has been built, the ARG doesn’t automatically become an environment variable inside the running container.

ARG APP_VERSION=1.0
RUN echo "Building version $APP_VERSION"

The value is available while Docker is executing the build, but it’s not something your application can read later as $APP_VERSION just because it was declared with ARG. This means the following doesn’t print anything as $APP_VERSION isn’t available after image is build:

docker container run myimage echo "$APP_VERSION"

When to reach for ARG?

Reach for ARG when you need to change something about the build without changing the Dockerfile.

Good examples include:

  • Selecting a base-image version.
  • Choosing a build configuration.
  • Passing a version number into a build step.
  • Changing a dependency or tool version during CI.

If the value needs to exist when the container runs, ARG is probably not what you want.

What ENV Does?

ENV defines an environment variable that persists into the image and is available to processes running in containers created from it.

For example:

ENV APP_ENV=production
ENV PORT=8080

A process inside the container can then read:

echo $APP_ENV

and get:

production

You can also override an ENV value when starting the container (-e option):

docker container run -e APP_ENV=staging myapp

So unlike ARG, ENV is primarily about runtime configuration.

Warning

There is one important detail: ENV values become part of the image configuration. That means they are not a good place for secrets.

Don’t do this:

ENV DATABASE_PASSWORD=supersecret

If something is sensitive, use Docker’s secret/config mechanisms or your deployment platform instead.

When to reach for ENV?

Reach for ENV when the value should be available to the application or processes inside the running container.

Good examples include:

  • NODE_ENV=production
  • PORT=8080
  • Application configuration defaults.
  • Paths such as PATH or JAVA_HOME.

If you only need the value while building, prefer ARG.

What LABEL Does?

LABEL attaches metadata to the image.

For example:

LABEL org.opencontainers.image.title="myapp"
LABEL org.opencontainers.image.version="1.4.0"
LABEL org.opencontainers.image.source="https://github.com/example/myapp"

These values aren’t environment variables, and they aren’t meant to configure your application.

They’re information about the image itself.

You can inspect them later:

docker image inspect myapp

and see the labels as part of the image metadata.

Labels are especially useful for things like:

  • Image version information.
  • Source repository information.
  • Documentation links.
  • Build or release metadata.
  • Ownership or organizational information.

When to reach for LABEL?

Reach for LABEL when you’re thinking:

“I want to describe this image, not configure the application.”

For example, a CI pipeline might add the Git commit, source repository, or release version as image metadata.

How They Work Together?

These instructions become easier to understand when you see them in the same Dockerfile:

ARG NODE_VERSION=22

FROM node:${NODE_VERSION}

ENV NODE_ENV=production
ENV PORT=8080

LABEL org.opencontainers.image.title="myapp"
LABEL org.opencontainers.image.version="1.4.0"

RUN npm install

Each instruction has a different purpose:

  • ARG NODE_VERSION → controls the build.
  • ENV NODE_ENV → configures the runtime.
  • LABEL ... → describes the image.

Think about the lifecycle:

                BUILD                    IMAGE                    RUNNING CONTAINER
                  │                        │                              │
                  │                        │                              │
                ARG ──────────────>        │                              │
                  │                        │                              │
                  │                    LABEL ───────────────────────────> metadata
                  │                        │                              │
                  │                      ENV ───────────────────────────> environment

The biggest distinction is not syntax. It’s when and why the value exists.

Note

A useful rule of thumb: use ARG for build-time inputs, ENV for runtime environment, and LABEL for image metadata. If you’re unsure which one to use, first ask: “Who needs this value, and when?”

Wrapping Up

ARG, ENV, and LABEL aren’t three ways of doing the same thing.

ARG helps you control the build.

ENV helps configure the container at runtime.

LABEL helps describe the image itself.

So when you reach for one, think about the job first:

  • Need it during docker build?ARG
  • Need the application to see it at runtime?ENV
  • Need to attach information about the image?LABEL

That’s the distinction that makes these three Dockerfile instructions easy to reason about.

Last updated on