✦ For everyone, free.

Practical knowledge for real and everyday life

Home

11.1.3.1 Dockerfile Secret Avoidance

A focused guide to Dockerfile Secret Avoidance, connecting core concepts with practical Docker and container operations.

Dockerfile secret avoidance refers to the specific practices needed within a Dockerfile itself to prevent a sensitive value from ever being written into one of the image's persisted layers, since simply being cautious about the final image's runtime configuration isn't enough if a secret was ever exposed during the build process itself.

The Mistake of Embedding a Secret Directly

Directly writing a secret into a file or environment variable within a standard RUN or ENV instruction persists it into the resulting layer.

ENV API_KEY=secret123

This value becomes part of the image's metadata, inspectable by anyone with access to the image, regardless of whether the application actually uses this hardcoded value at runtime.

Why Deleting a Secret Later in the Dockerfile Doesn't Help

A secret written in one instruction and deleted in a later one remains present in the earlier instruction's own layer, since each instruction typically creates its own persisted layer.

RUN echo "secret123" > /tmp/key
RUN rm /tmp/key

The first layer still contains this secret, regardless of the second instruction's deletion.

Using a Multi-Stage Build to Limit Exposure

A multi-stage build can use a secret only within an intermediate stage, never carrying that stage's layers forward into the final image.

FROM alpine AS builder
RUN --mount=type=secret,id=api_key some-build-step-needing-the-secret

FROM alpine
COPY --from=builder /app/output /app/output

The final image inherits only the builder stage's output, not its layers, meaning the secret never reaches the final image's history at all when combined with BuildKit's secret mounting.

Using BuildKit Secrets as the Correct, Purpose-Built Mechanism

BuildKit's dedicated --mount=type=secret provides a way to use a secret during a build without persisting it in any layer.

RUN --mount=type=secret,id=npm_token npm install
Why Dockerfile Secret Avoidance Matters

Avoiding these specific Dockerfile-level mistakes, and using BuildKit's purpose-built secret mounting instead, is essential for preventing a sensitive value from ever being embedded in an image's persisted layers in the first place.