dockernpmdocker-composenode-modulesnpm-install

Docker fails to update node_modules after dependency changes in package.json


I'm experiencing an issue where Docker doesn't seem to update the node_modules folder after I modify dependencies in package.json. Even after rebuilding the Docker image and container, the application still throws errors related to the missing dependencies. The changes to node_modules only take effect if I completely remove the container and its associated volume before rebuilding.

Dockerfile:

FROM node:22-alpine

RUN npm install -g npm@latest

USER node

WORKDIR /app

COPY --chown=node:node package.json package-lock.json ./

RUN npm install

COPY . .

EXPOSE 5173

CMD ["npm", "run", "dev"]

docker-compose.yml

services:
  npm-test:
    build: .
    ports:
      - "5173:5173"
    volumes:
      - .:/app
      - node_modules_docker:/app/node_modules

volumes:
  node_modules_docker:

Steps to reproduce:

  1. Build and run the container (everything works):

    docker compose up --build
    
  2. Remove significant dependencies from package.json e.g. @vitejs/plugin-react

  3. Run npm install to update package-lock.json

  4. Stop and remove the container, images, and volumes, then rebuild (use the following commands to delete everything, or replace IDs to target specific ones):

    docker stop $(docker ps -q)
    docker rm $(docker ps -aq)
    docker rmi $(docker images -q)
    docker volume rm $(docker volume ls -q)
    
    docker compose up --build
    
  5. The following error will show up:

    Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@vitejs/plugin-react' imported from /app/node_modules/.vite-temp/vite.config.ts.timestamp-1733299382139-6e1c72bf771df.mjs

  6. Add back the missing dependencies to package.json and run npm install

  7. Build and run the container again:

    docker compose up --build
    
  8. The app should work again (it is "the same" as in the beginning), but the error persists

Repository with MRE


Solution

  • To achieve the desired behavior where:

    1. node_modules is updated on container startup when package.json changes, without needing to remove volumes
    2. code changes are reflected immediately in the Docker container during development

    I had to modify my Dockerfile as follows:

    1. Replaced this:
    COPY --chown=node:node package.json package-lock.json ./
    RUN npm install
    COPY . .
    

    with this:

    RUN mkdir -p ./node_modules && chown -R node:node ./node_modules
    
    1. Replaced this:
    CMD ["npm", "run", "dev"]
    

    with this:

    CMD ["sh", "-c", "npm install && npm run dev"]
    

    Summary

    Final Dockerfile

    FROM node:22-alpine
    
    RUN npm install -g npm@latest
    
    USER node
    
    WORKDIR /app
    
    RUN mkdir -p ./node_modules && chown -R node:node ./node_modules
    
    EXPOSE 5173
    
    CMD ["sh", "-c", "npm install && npm run dev"]