Docker

Lesson 07

ARG, ENV, and secrets

Separate build-time arguments, runtime environment variables, and secrets so sensitive values are not baked into images.

Good Code

compose.yaml
services:
  app:
    build:
      context: .
      args:
        # Build args are for build-time choices, not secrets.
        NODE_VERSION: "22"
    environment:
      NODE_ENV: production
      DATABASE_URL_FILE: /run/secrets/database_url
    # Secrets are mounted at runtime instead of baked into the image.
    secrets:
      - database_url

secrets:
  database_url:
    file: ./secrets/database_url.txt

Bad Code

Dockerfile
FROM node:22-alpine

# Passing secrets through ARG can leave them in build history.
ARG DATABASE_URL
# ENV keeps the secret in the final image config.
ENV DATABASE_URL=$DATABASE_URL
ENV API_TOKEN=super-secret-token

COPY . .
RUN npm run build
CMD ["npm", "start"]

Review Notes

What to review

Good Code

The good version treats build arguments, runtime environment, and secrets as different concerns.

Bad Code

The bad version passes secrets through ARG and stores them in ENV, making sensitive values part of the image configuration or build history.

Takeaways

  • Secrets should be supplied at runtime or through secret mounts, not stored in image layers.