Node modules missing in Docker volume after successful npm install

I’m having trouble with my Docker setup for a Node.js worker. Here’s what’s happening:

  1. I run docker-compose build and it installs all npm modules correctly.
  2. But when I do docker-compose up, I get an error saying it can’t find the ‘async’ module.
  3. I checked and the node_modules folder is empty both on my host and in the container.

My Dockerfile copies package.json and runs npm install. The docker-compose file sets up a volume for the worker folder.

I can fix this by running npm install on my host, but I want the container to handle dependencies.

What am I missing? How can I make sure the npm modules are available when I run the container?

# docker-compose.yml snippet
worker:
  build: ./worker
  command: npm start
  volumes:
    - worker/:/worker/
  # other config...

Any ideas on what might be causing this issue?

This issue often stems from volume mounting overwriting the container’s node_modules. When you mount your host directory to /worker/ in the container, it masks the installed modules.

A solution is to use a named volume for node_modules:

worker:
  build: ./worker
  command: npm start
  volumes:
    - ./worker:/worker
    - /worker/node_modules

This keeps node_modules in the container separate from your host. Also, consider moving ‘npm install’ to your entrypoint script instead of the Dockerfile. This ensures fresh installs on container start.

Remember to rebuild your image after changes. If problems persist, check your .dockerignore file isn’t excluding necessary files.

I’ve encountered this issue before, and it can be quite frustrating. One thing that worked for me was tweaking the Dockerfile to use a multi-stage build. Here’s what I did:

Created a ‘builder’ stage to install dependencies
Copied only the necessary files to the final stage

This approach ensures that node_modules are properly installed and included in the final image, regardless of volume mounts. Here’s a simplified example:

FROM node:14 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install

FROM node:14
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
CMD ["npm", "start"]

This method has the added benefit of reducing the final image size. Give it a try and see if it resolves your issue. If not, double-check your .dockerignore file to ensure it’s not excluding important files.