Build secrets

Some builds need a credential: a private registry token, an SSH key. BuildKit secrets give it to one RUN only, without writing it into any layer, history or cache key.

How it works

RUN --mount=type=secret,id=npm_token,env=NPM_TOKEN puts the secret in a variable of that command only (or in a file, /run/secrets/<id> by default). docker build --secret id=npm_token,env=NPM_TOKEN provides it; in Compose, build: secrets: in the service and a top-level secrets: entry with file: or environment:.

What breaks

ARG and ENV values end up in the image's history and configuration, visible with docker history and docker inspect, and Docker's build checks flag them (SecretsUsedInArgOrEnv). A file copied, then deleted by a later step, stays in the layer that copied it. A multi-stage build hides the value from the final image, not from the build cache.

In a Dockerfile

# syntax=docker/dockerfile:1
FROM node:20-alpine
WORKDIR /app
COPY package*.json .npmrc ./
RUN --mount=type=secret,id=npm_token,env=NPM_TOKEN npm ci --omit=dev

See it break, then fix it

Write the Dockerfile or the compose file, type the docker commands, and watch a simulated server run them through reboots, upgrades and traffic. Free to start.