Docker and private packages with .npmrc
Asked Answered
E

5

20

I am using a .npmrc file to configure a private repo (font-awesome-pro).

It works well without docker.

But with docker, the npm install fails:

npm ERR! code E401
npm ERR! 404 401 Unauthorized: @fortawesome/fontawesome-pro-light@https://npm.fontawesome.com/7D46BEC2-1565-40B5-B5FC-D40C724E60C6/@fortawesome/fontawesome-pro-light/-/fontawesome-pro-light-5.0.12.tgz

I have read the doc from NPM : Docker and private packages, but I don't know how to apply it with docker-compose.yml and I not sure passing variables is the solution (?). Is it possible that the .npmrc file is not read during installation inside the docker instance ? Am I missing something ?

Here is my docker-compose.yaml :

version: '2.1'
services:
  app:
    image: node:8.9.4
    # restart: always
    container_name: jc-vc
    environment:
      - APP_ENV=${JC_ENV:-dev}
      - HOST=0.0.0.0
      - BASE_URL=${JC_BASE_URL}
      - BROWSER_BASE_URL=${JC_BROWSER_BASE_URL}
    working_dir: /usr/src/app
    volumes:
      - ${DOCKER_PATH}/jc/vc/app:/usr/src/app
    command: npm install
    # command: npm run dev
    # command: npm run lintfix
    # command: npm run build
    # command: npm start
    expose:
      - 3000
      
  nginx:
    image: nginx
    logging:
      driver: none
    # restart: always
    volumes:
      - ${DOCKER_PATH}/jc/vc/nginx/www:/usr/share/nginx/html
      - ${DOCKER_PATH}/jc/vc/nginx/default.${JC_ENV:-dev}.conf:/etc/nginx/nginx.conf
      - ${DOCKER_PATH}/jc/vc/nginx/.htpasswd:/etc/nginx/.htpasswd
      - ${DOCKER_PATH}/jc/letsencrypt:/etc/letsencrypt
    container_name: jc-nginx-vc
    depends_on:
      - app
    ports:
      - ${PORT_80:-4020}:${PORT_80:-4020}
      - ${PORT_443:-4021}:${PORT_443:-4021}

and my .npmrc (with replaced token) :

@fortawesome:registry=https://npm.fontawesome.com/
//npm.fontawesome.com/:_authToken=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXX
Eccentric answered 14/6, 2018 at 7:18 Comment(0)
E
-3

package-lock.json needs to be re-generate with the new .npmrc file. Delete it package-lock.json and recreate it with npm install then redeploy the image.

Eccentric answered 24/9, 2018 at 7:21 Comment(3)
By removing this file you are weakening stability. The lock file is there for a reason and if you understand this reason you might understand why removing it should not be considered a solution. For once, the lock file is assuring your code isn't adopting untested (by means of known to work with your code) dependencies automatically which might cause you lots of trouble when it comes to reproducing bugs reported by users.Mongolic
I meant to delete the current one and then re-generate it so the new one takes into account the .npmrc file. I have updated the answer to address your point.Eccentric
@Eccentric I think you need to specify when to delete the package-lock.json. If you mean during development and pre-testing, I haven't tested that this works but sure. If you mean as part of your Docker build, not a great idea. This is an important distinction that really needs to be part of your answer.Barnard
F
11

The correct way to fix this, as documented in the link you reference, is to use arg variables in the dockerfile. I think the bit you're missing is how to do this in compose:

version: "3"
services:
  myapp:
    build:
      context: "."
      args:
        NPM_TOKEN: "s3kr!t"

You need to reference this argument in your dockerfile and create a .npmrc file in the root of your project:

//registry.npmjs.org/:_authToken=${NPM_TOKEN}

I like to generate this in the dockerfile to minimise the risk of exposure (but, be aware, the token is still stored in the image's layers), so it would look something like this:

FROM node:current-buster-slim

ARG NPM_TOKEN  

WORKDIR /app

COPY package.json /app/package.json  

RUN echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > /app/.npmrc && \
    npm install && \
    rm -f /app/.npmrc


COPY . /app/
CMD npm start

You can then run docker-compose build myapp and get a good result. This solution still suffers from having the secret in your compose file and in the docker images, but this is only a sketch for SO. In the real world you'd not want to put your secrets in your source-files so realistically you'd replace the secret with a dynamic secret that has a short Time To Live (TTL) and a single-use policy (and you'd probably want to use Hashicorp Vault to help with that).

Floristic answered 26/2, 2021 at 12:55 Comment(4)
Thanks for the explanation. For dummies like me, what does SO mean?Evince
StackOverflow :)Floristic
A buildkit extension is coming up to provide secret management in docker compose. As of July 15 2021 it is not released yet : github.com/docker/compose/pull/7046Calgary
Does using multi stage build prevent exposure of .npmrc in any layers? That is, build stage would deal with npm install, delete .nprmc and production stage would just merely copy files from build.Ezarras
F
5

I ran into the same problem, but in my case I forgot to copy the .npmrc file to the container, and only copied the package.json, added this to my Dockerfile before it does npm install:

COPY .npmrc ./
Franconia answered 27/2 at 13:54 Comment(0)
D
0
  1. In the root directory of your project, create a custom .npmrc file with the following contents:

    //registry.npmjs.org/:_authToken=${NPM_TOKEN}

  2. Now add these commands to Dockerfile

    COPY .npmrc .npmrc
    COPY package.json package.json
    RUN npm install
    RUN rm -f .npmrc

That should fix the issue, hope that helps

Dagall answered 24/4, 2021 at 15:30 Comment(0)
O
-1

We discovered that one of our GitHub repositories was accidentally public and moved it to a private AWS CodeArtifact repository. Then we had this same issue.

The root cause of the problem was that we had package-lock.json checked into GitHub (a good practice) but inside of there, package-lock.json was still referencing GitHub.

The fix, was to remove package-lock.json (a one-time event, since we're switching registries) and regenerate it. We then compared it to make sure that only the package that we expected to change was modified to point to the new registry.

Here are the steps (Windows):

del package.json
npm install

And then compare package.json to ensure only the registry has changed.

Olden answered 29/9, 2023 at 16:0 Comment(0)
E
-3

package-lock.json needs to be re-generate with the new .npmrc file. Delete it package-lock.json and recreate it with npm install then redeploy the image.

Eccentric answered 24/9, 2018 at 7:21 Comment(3)
By removing this file you are weakening stability. The lock file is there for a reason and if you understand this reason you might understand why removing it should not be considered a solution. For once, the lock file is assuring your code isn't adopting untested (by means of known to work with your code) dependencies automatically which might cause you lots of trouble when it comes to reproducing bugs reported by users.Mongolic
I meant to delete the current one and then re-generate it so the new one takes into account the .npmrc file. I have updated the answer to address your point.Eccentric
@Eccentric I think you need to specify when to delete the package-lock.json. If you mean during development and pre-testing, I haven't tested that this works but sure. If you mean as part of your Docker build, not a great idea. This is an important distinction that really needs to be part of your answer.Barnard

© 2022 - 2024 — McMap. All rights reserved.