Why does npm rebuild in docker work but npm install doesn’t

Solution for Why does npm rebuild in docker work but npm install doesn’t
is Given Below:

I have a node project that accesses some private repos. When I submit the project to CircleCI with the following config file (inherited from another developer) and the following Dockerfile, the build works. However, if I replace the npm rebuild in the Dockerfile with npm install, the build fails due to not being able to fetch some private repos I’m using. I know (or think I know) this is the case cause if I run the docker image with a shell and remove the private repos from the package.json, npm install works just fine. Here’s my assumption of what’s going on.

  1. The npm ci in circleCi works because CircleCi has access to our Github SSH keys, and doing this installs the packages in the container this build is running in
  2. When I run the docker build command AFTER CircleCi runs npm ci, the node_modules already has all the packages I need (due to CircleCi installing them. If this is the case, I guess I technically don’t need to do another npm install in the Dockerfile)
    2.a This seems like I’m running a docker build (the penultimate “run” command in the circleci config file) within a docker “build” that’s defined by the CircleCi config….
  3. When I run npm install in the Dockerfile, it errs because I can’t pull down the private repos due to no SSH access. However, npm rebuild just re-compiles the already installed packages

Is that correct or am I way off? And if that is correct, then I guess if we weren’t using any private repos I could just have CircleCi run the build command (ie no npm install, apt get, etc that I’m also doing in the Dockerfile) and use the Dockerfile as the “config” rather than having essentially the same config defined in the circleci.yaml file, yeah?

And yes, I know I can clean up that Dockerfile a bit… Just want to get an understanding of what’s going on first.

Hope that’s somewhat clear and thanks in advance for any clarification.

    docker:
      - image: circleci/node:14.17.3
    environment:
      - DOCKER_TAG: dev
    steps:
      - checkout
      - run:
          name: Install npm v6.12.0
          command: sudo npm install -g [email protected]
      - restore_cache:
          key: cache-{{ checksum "package.json" }}
      - run:
          name: npm install ci
          command: npm ci --only=production
      - save_cache:
          key: cache-{{ checksum "package.json" }}
          paths:
            - ./node_modules
      - run:
          name: npm prune
          command: npm prune --production
      - setup_remote_docker
      - run:
          name: Install dependencies
          working_directory: /
          command: |
            sudo apt-get update --fix-missing
            sudo apt install -y python-pip python-dev
            sudo pip install awscli
      - run:
          name: build
          command: docker build --no-cache -t <repo>:<tag>
      - run:
          name: push
          command: make push (push to ECR)

# Using official Node.js base image
FROM node:14.17.3-slim

# Create a directory for our application and one for its log files
# Update the image and install supervisord which we will use to run the application
RUN mkdir /opt/app 
  && mkdir /var/log/app 
  && apt-get update 
  && apt-get -y upgrade 
  && apt-get install -y supervisor bzip2 build-essential python python-pip 
  && pip install awscli 
  && npm install -g sequelize-cli

# Add our supervisord configuration file
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

WORKDIR /opt/app
ADD . /opt/app

# Run an npm rebuild
RUN npm rebuild

# Set NODE_PATH
ENV NODE_PATH /opt/app
# Expose the port the app listens on
EXPOSE 5000

# Inject the host's NODE_ENV environment variable
ENV NODE_ENV $NODE_ENV

# Run the app with supervisord
CMD ["bin/boot.sh"]