docker build + private NPM (+ private docker hub) docker build + private NPM (+ private docker hub) docker docker

docker build + private NPM (+ private docker hub)


I found a somewhat elegant-ish solution in creating a base image for your node.js / io.js containers (you/iojs):

  1. log in to your private npm registry with the user you want to use for docker
  2. copy the .npmrc file that this generates

Example .npmrc:

registry=https://npm.mydomain.com/username=dockerUseremail=docker@mydomain.comstrict-ssl=falsealways-auth=true//npm.mydomain.com/:_authToken="someAuthToken"
  1. create a Dockerfile that copies the .npmrc file appropriately.

Here's my Dockerfile (based on iojs:onbuild):

FROM iojs:2.2.1MAINTAINER YourSelf# Exclude the NPM cache from the imageVOLUME /root/.npm# Create the app directoryRUN mkdir -p /usr/src/appWORKDIR /usr/src/app# Copy npm configCOPY .npmrc /root/.npmrc# Install appONBUILD COPY package.json /usr/src/app/ONBUILD RUN npm installONBUILD COPY . /usr/src/app# RunCMD [ "npm", "start" ]
  1. Make all your node.js/io.js containers FROM you/iojs and you're good to go.


For those who are finding this article via google and are still looking for an alternative way that doesn't involve leaving you private npm tokens on your docker images and containers:

We were able to get this working by doing the npm install prior to the docker build (By doing this it lets you have your .npmrc outside of your image\container). Once the private modules have been installed locally you can copy your files across to the image as part of your build:

    # Make sure the node_modules contain only the production modules when building this image    COPY . /usr/src/app

You also need to make sure that your .dockerignore file doesn't exclude the node_modules folder.

Once you have the folder copied into your image, the trick is to to npm rebuild instead of npm install. This will rebuild any native dependancies that are effected by any differences between your build server and your docker OS:

    FROM nodesource/vivid:LTS    # For application location, default from nodesource is /usr/src/app    # Make sure the node_modules contain only the production modules when building this image    COPY . /usr/src/app    WORKDIR /usr/src/app    RUN npm rebuild    CMD npm start


In 2020 we've got BuildKit available. You don't have to pass secrets via COPY or ENV anymore, as it's not considered safe.

Sample Dockerfile:

# syntax=docker/dockerfile:experimentalFROM node:13-alpineWORKDIR /appCOPY package.json yarn.lock ./RUN --mount=type=ssh --mount=type=secret,id=npmrc,dst=$HOME/.npmrc \  yarn install --production --ignore-optional --frozen-lockfile# More stuff...

Then, your build command can look like this:

docker build --no-cache --progress=plain --secret id=npmrc,src=/path-to/.npmrc .

For more details, check out: https://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-secret-information