Skip to Content
Pass Env Vars Without Hard-Coding Secrets
Intermediate
0 likes
Tutorials

Pass Env Vars Without Hard-Coding Secrets

Pass variables from your shell, from an env file and from a Compose secret, and make Compose refuse to start when a required one is missing. After this, you can keep real values out of your files and your commands.

A password written in a Dockerfile, a Compose file or a docker run command ends up in Git, in your shell history and in docker inspect. The safer habit is to name the variable and let it come from somewhere else. This page shows the four ways to do that, from quickest to most careful. The values are made up.

Pass a variable from your shell

-e NAME with no value copies the variable from your current shell into the container. The secret is not in the command you type or save.

$env:API_KEY = "not-a-real-key"
docker run --rm -e API_KEY alpine:3.24 sh -c 'echo key length: ${#API_KEY}'
Remove-Item Env:API_KEY
key length: 14

I printed only the length, so the key is not in the output either. The variable exists in the container for that run. Remove it from your shell when you are done.

Pass a file of variables

For more than two or three, use --env-file. The file is not committed to Git.

Set-Content app.env "API_KEY=not-a-real-key`nREGION=eu"
docker run --rm --env-file app.env alpine:3.24 sh -c 'echo region: $REGION'
region: eu

The format is plain NAME=value lines. Quotes are not removed, so write NAME=value and not NAME="value".

Make Compose refuse to start without a value

In a Compose file, ${API_KEY} is replaced by the value from your shell or .env. If the variable is missing, it silently becomes an empty string, and the container starts without a key. Add :? and a message, and Compose stops instead.

services:
  app:
    image: alpine:3.24
    environment:
      API_KEY: ${API_KEY:?API_KEY is required, set it in your shell or .env}
    command: ["sh", "-c", "echo key length: $${#API_KEY}"]
Set-Location envvars-stack
docker compose run --rm app 2>&1 | ForEach-Object { $_.ToString().Trim() }
$env:API_KEY = "not-a-real-key"
docker compose run --rm app 2>$null
Remove-Item Env:API_KEY
error while interpolating services.app.environment.API_KEY: required variable API_KEY is missing a value: API_KEY is required, set it in your shell or .env
key length: 14

The first run fails at once with your message, and nothing starts. With the variable set, the container runs. A clear failure at start is far better than an app that fails later with "401 Unauthorized" and no hint why.

Use a secret file when the value matters

A variable is visible to anyone who can run docker inspect. For a real password, mount a file instead.

not-a-real-token
services:
  app:
    image: alpine:3.24
    secrets:
      - token
    command: ["sh", "-c", "wc -c < /run/secrets/token"]
secrets:
  token:
    file: ./token.txt
docker compose -f compose.secret.yaml run --rm app 2>$null
17

The file is mounted under /run/secrets/ and is not part of the container's environment. The number is its size in bytes: the token and a line break. Your program reads the file, and many official images accept a _FILE variant of their settings for this.

⚠ Warning: A file called .env or token.txt goes into .gitignore before the first commit. If a secret was committed even once, treat it as public and replace it.

Related course: Docker Intermediate.

About

Pass variables from your shell, from an env file and from a Compose secret, and make Compose refuse to start when a required one is missing. After this, you can keep real values out of your files and your commands.

Responsible
Mary Q
Last Update
08/08/2026
Reading Time
3 min
Was this helpful?
​ 0 ​ 0

Comments (0)

Sign in to comment

No comments yet.