2

I'm running a small nodejs microservice in docker. When I run the container standalone with docker run -p 3000:3000 {image-name} it works fine. However when I attempt to run it from docker-compose, I get the following error:

user_1     | Error: Cannot find module 'express'
user_1     | Require stack:
user_1     | - /usr/src/app/src/app.js
user_1     |     at Function.Module._resolveFilename (internal/modules/cjs/loader.js:815:15)
user_1     |     at Function.Module._load (internal/modules/cjs/loader.js:667:27)
user_1     |     at Module.require (internal/modules/cjs/loader.js:887:19)
user_1     |     at require (internal/modules/cjs/helpers.js:74:18)
user_1     |     at Object.<anonymous> (/usr/src/app/src/app.js:12:17)
user_1     |     at Module._compile (internal/modules/cjs/loader.js:999:30)
user_1     |     at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)
user_1     |     at Module.load (internal/modules/cjs/loader.js:863:32)
user_1     |     at Function.Module._load (internal/modules/cjs/loader.js:708:14)
user_1     |     at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12) {
user_1     |   code: 'MODULE_NOT_FOUND',
user_1     |   requireStack: [ '/usr/src/app/src/app.js' ]
user_1     | }

Here is the Dockerfile for the node service I'm trying to run

FROM node:12

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

COPY package.json /usr/src/app

# Install npm packages
RUN npm install

COPY . /usr/src/app


EXPOSE 3000

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

To add, express is defined as a dependency in the package.json file, it's not that.

Here is the docker-compose.yml (Relevant snippet)

    user: 
        build: ./user-service
        ports: 
            - "2008:3000"
        volumes:
            - type: bind
              source: ./user-service
              target: /usr/src/app
        working_dir: /usr/src/app
        networks: 
            - backend

    redis: 
        image: "redis:latest"
        ports: 
            - "6379:6379"
        networks:
            - backend

The reason I bind the volume is because I want to hot reload the application whenever I make a change.

What I've tried:

  • Rebuilding the image

  • opening a shell inside the container to ensure the files are mapped out correctly - they are.

  • clearing all my cache and images, and rebuilding everything just to be sure nothing is cached.

4
  • Double-check the dir inside the container the error says: requireStack: [ '/usr/src/app/src/app.js'. You can notice the double src/ maybe you have a wrong map folder or something like that. Commented Sep 3, 2021 at 12:14
  • thought that at first, but sadly not - It's correctly mapped. Commented Sep 3, 2021 at 12:19
  • In this case for debug you must start the container then attach a shell to it and try yourself the commands npm install, npm start and compare the folder structure between the container and your dev env. Commented Sep 3, 2021 at 13:55
  • Did you solve your problem? Commented Sep 10, 2021 at 14:00

4 Answers 4

5

I had the same problem recently, and solved it by creating an anonymous volume for the node_modules folder to prevent it from being overwritten:

volumes: 
  - ./node:/usr/src/app
  # Anonymous volume:
  - /usr/src/app/node_modules

You also need to give permissions to the node user to access the volume:

RUN chown -R node:node node_modules
Sign up to request clarification or add additional context in comments.

1 Comment

do i need to add ./node:/usr/src/app too?
2

Bring down all containers

docker compose down -v

In your docker-compose.yml file map node_volumes directory

volumes:
    - .:/usr/src/app
    - /usr/src/app/node_modules

Build and run containers. (Ensure to delete node_modules directory in root of nodejs app in dockerhost)

docker compose build --no-cache
docker compose up -d

refer https://stackoverflow.com/a/45413240/8811037 for more details

Comments

0

docker container is not found your node_modules directory

So you have to manually run the npm install inside of your docker image

docker-compose run user npm install

format: docker-compose run [image_name] [command]

command: npm install

In your example

     user:  //image name
        build: ./user-service
        ports: 
            - "2008:3000"
        volumes:
            - type: bind
              source: ./user-service
              target: /usr/src/app
        working_dir: /usr/src/app
        networks: 
            - backend

    redis: //image name
        image: "redis:latest"
        ports: 
            - "6379:6379"
        networks:
            - backend

Comments

0

Bring down all containers, remove persistant volumes if any.

docker compose down -v

In your docker-compose.yml file map node_volumes directory

volumes:
    - .:/usr/src/app
    - /usr/src/app/node_modules

Build and run containers. (Ensure to delete node_modules directory in root of nodejs app in dockerhost)

docker compose build --no-cache
docker compose up -d

refer https://stackoverflow.com/a/45413240/8811037 for more details

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.