Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker and private packages with .npmrc

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
like image 935
Thomas Avatar asked Jun 14 '18 07:06

Thomas


People also ask

Can you have private npm packages?

With npm private packages, you can use the npm registry to host code that is only visible to you and chosen collaborators, allowing you to manage and use private code alongside public code in your projects. Private packages always have a scope, and scoped packages are private by default.

What is Npmrc file used for?

Per-project config file When working locally in a project, a . npmrc file in the root of the project (ie, a sibling of node_modules and package. json ) will set config values specific to this project. Note that this only applies to the root of the project that you're running npm in.

What is difference between ADD and copy in Dockerfile?

COPY is a docker file command that copies files from a local source location to a destination in the Docker container. ADD command is used to copy files/directories into a Docker image. It only has only one assigned function. It can also copy files from a URL.


1 Answers

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).

like image 145
Software Engineer Avatar answered Sep 29 '22 01:09

Software Engineer