Docker cookbook · Intermediate

Use private package credentials in a build without leaking them

Install from a private npm, PyPI or Maven registry during the build without the token ending up in the image.

Create a free account to save this page, take notes and track your progress. Sign in

Approach

Mount the credential only for the RUN step that needs it with a BuildKit secret mount. It never appears in a layer, the image config or the build history.

Solution

# syntax=docker/dockerfile:1
FROM node:24-alpine
WORKDIR /app
COPY package.json package-lock.json ./
RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ci --omit=dev
COPY . .
CMD ["node", "server.js"]
docker build --secret id=npmrc,src=$HOME/.npmrc -t app:dev .
# in CI: docker build --secret id=npmrc,env=NPMRC_CONTENT ...

Pitfalls

  • ARG NPM_TOKEN or ENV NPM_TOKEN: visible in docker history or docker inspect.
  • COPY .npmrc . followed by RUN rm .npmrc: the file stays in the earlier layer.

Variations

  • SSH mounts (--mount=type=ssh) for private Git dependencies.
  • Build-time secrets from CI secret stores via docker/build-push-action's secrets input.

Further reading: Build secrets

Reference: https://docs.docker.com/build/building/secrets/

More Docker recipes

Was this page helpful?