Skip to content

Instantly share code, notes, and snippets.

@u2mejc
Last active August 30, 2024 18:02
Show Gist options
  • Save u2mejc/46acf89c848fdbd4068883d3a282b7df to your computer and use it in GitHub Desktop.
Save u2mejc/46acf89c848fdbd4068883d3a282b7df to your computer and use it in GitHub Desktop.
How to use NPM securely inside Docker image Dockerfile builds

Securely Accessing Private NPM Repos When Building Docker Containers

This topic has been discussed at length before, with different solutions1, but it still seems difficult re-assuring engineers that it's possible and safe to use secret environment variables during docker builds. It seems hotly debated if secrets should ever be in environment variables, with some saying all config goes in env2 and others doing their best to make it hard for people to use environment variables3.

Let's step through an example of how to use Docker secrets to create secure environment variables for npm during a Dockerfile build:

Example Dockerfile

This example copies in a npm package.json and package-lock.json file, for use with npm ci

Note: The backslash in the echo command allows echo to write the environment variable name to disk, instead expanding it

FROM node:20

ARG NPM_REPOSITORY

RUN echo "//${NPM_REPOSITORY}:_authToken=\${NPM_TOKEN}" >> ~/.npmrc
RUN npm config set registry "https://${NPM_REPOSITORY}"

COPY package.json .
COPY package-lock.json .

RUN --mount=type=secret,id=npmtoken \
   NPM_TOKEN=$(cat /run/secrets/npmtoken) npm ci --env=production

How to build

Note from Docker's build secret docs: "When you use secrets from environment variables, you can omit the env parameter to bind the secret to a file with the same name as the variable."

When building, you'll need your package.json and package-lock.json in the same directory as the Dockerfile.

docker build --build-arg NPM_REPOSITORY="$NPM_REPOSITORY" --secret id=NPM_TOKEN --tag testbuild .

How to verify secrets are not preserved

  1. Check the contents of ~/.npmrc: docker run testbuild /usr/bin/env bash -c 'cat ~/.npmrc'
  2. Check the Docker image layer history: docker history --no-trunc testbuild

This flow gives you the flexibility of environment variables, without the risk of committing them to the Docker image.

Happy sailing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment