To install private npm packages in a Docker container, you will need to use Docker's build-time variables.
Background: runtime variables
You cannot install private npm packages in a Docker container using only runtime variables. Consider the following Dockerfile:
FROM node
COPY package.json package.json
RUN npm install
# Add your source files
COPY . .
CMD npm start
Which will use the official Node.js image, copy the package.json
into our container, installs dependencies, copies the source files and runs the start command as specified in the package.json
.
In order to install private packages, you may think that we could just add a line before we run npm install
, using the ENV parameter:
ENV NPM_TOKEN=00000000-0000-0000-0000-000000000000
However, this doesn't work as you would expect, because you want the npm install to occur when you run docker build
, and in this instance, ENV
variables aren't used, they are set for runtime only.
Instead of run-time variables, you must use a different way of passing environment variables to Docker, available since Docker 1.9: the ARG parameter.
Create and check in a project-specific .npmrc file
A complete example that will allow you to use --build-arg
to pass in your NPM_TOKEN requires adding a .npmrc
file to the project.
Use a project-specific .npmrc
file with a variable for your token to securely authenticate your Docker image with npm.
-
In the root directory of your project, create a custom .npmrc
file with the following contents:
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
Note: that you are specifying a literal value of ${NPM_TOKEN}
. The npm cli will replace this value with the contents of the NPM_TOKEN
environment variable. Do not put a token in this file.
Check in the .npmrc
file.
Update the Dockerfile
The Dockerfile that takes advantage of this has a few more lines in it than the earlier example that allows us to use the .npmrc
file and the ARG
parameter:
FROM node
ARG NPM_TOKEN
COPY .npmrc .npmrc
COPY package.json package.json
RUN npm install
RUN rm -f .npmrc
# Add your source files
COPY . .
CMD npm start
This adds the expected ARG NPM_TOKEN
, but also copies the .npmrc
file, and removes it when npm install
completes.
Build the Docker image
To build the image using the above Dockerfile and the npm authentication token, you can run the following command. Note the .
at the end to give docker build
the current directory as an argument.
docker build --build-arg NPM_TOKEN=${NPM_TOKEN} .
This will build the Docker image with the current NPM_TOKEN
environment variable, so you can run npm install
inside your container as the current logged-in user.
Note: Even if you delete the .npmrc
file, it will be kept in the commit history. To clean your secrets entirely, make sure to squash them.
Note: You may commit the .npmrc
file under a different name, e.g. .npmrc.docker
to prevent local build from using it.
Note: You may need to specify a working directory different from the default /
otherwise some frameworks like Angular will fail.