Docker Environment Variable Precedence Tester

Work out which value the container actually gets. Prefix each line with its source: run, environment, env_file, dockerfile or shell.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Test. Nothing leaves this tab.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

Three layered sources

environment: wins, and the Dockerfile value is only the floor

dockerfile: ENV PORT=8080
env_file: PORT=9090
environment: PORT=3000

A variable set in your shell

Reaches nothing, and the Dockerfile default is what the container gets

shell: API_KEY=fromshell
dockerfile: ENV API_KEY=default

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Exporting a variable in your shell and expecting the container to see it

    Containers do not inherit the shell's environment. Compose reads it only for interpolating the compose file.

    Instead:Pass it explicitly with a bare key: environment: [API_KEY].

  2. Putting a value in a shared env_file to override a service's environment:

    environment: is more specific, so it always wins. The env_file value is simply ignored.

    Instead:Remove it from whichever place should not own it, so there is one source to check.

  3. Putting a credential in a Dockerfile ENV

    It is baked into the image metadata and readable with docker history by anybody who can pull the image.

    Instead:Pass it at run time, and use a build secret mount if it is needed during the build.

A container does not inherit your shell

That is the one people lose the most time to, because the same command works in a terminal and the container gets nothing.

The order, highest to lowest

-e on the command line, then environment: in the compose file, then env_file:, then the Dockerfile's ENV. Each is more specific than the one below it, which means a shared env_file cannot override a per-service value, and that is usually discovered by somebody trying exactly that.

Your shell is not on the list

Compose reads your environment only to fill in ${ } while parsing the compose file. To pass a variable from your shell into the container you have to say so, with a bare key and no value: environment: [API_KEY]. That is the only route.

.env is a fourth thing again

It populates ${ } in the compose file, from the project directory. It is not env_file:, it does not reach the container, and the same name can sit in both with different values and nothing will point that out.

Dockerfile ENV is a default and a disclosure

It is the value when nothing else supplies one, and it is baked into the image metadata, so anybody who can pull the image can read it with docker history. A credential in an ENV is a published credential.

A value set in two places is a bug waiting

Not because the resolution is ambiguous, it is not, but because whoever changes the losing one will believe they have changed the behaviour. One place per variable is worth more than knowing the order.

What this cannot see

Anything you did not paste, including whether a variable exists at all. It resolves the sources you describe, in your browser.