sunsets
sunsets

Reputation: 411

cannot find modules on docker even if I added a node_modules as volume when docker run

I'm trying to run docker but it can't find modules

I have already have docker image after build step and here's some information.

docker run --rm -v $(pwd):/code -v /code/node_modules -w /code $dockerBuilderImage npm run dist-admin-web

package.json has a script of dist-admin-web with rm -rf bin %% tsc

My docker file looks like

FROM node:12.18.2

COPY package.json ./
COPY package-lock.json ./

RUN npm install

(... some global installations)

As I said, when I do commands docker run and it doesn't work! FYI, I have docker-compose for local development and it works with that image.

My docker compose is following... (I've deleted unneccessary information like env..)

webpack_dev_server:
    build:
      context: ./
      dockerfile: Dockerfile
    image: nodewebpack_ts:12.18.2-ts3.5.2
    ports:
      - "3000:3000"
    volumes:
      - ./:/ROOT/
      - /ROOT/node_modules
    working_dir: /ROOT

As I know, I have to add node_modules at volumes because of this. That's why docker compose works

Upvotes: 1

Views: 370

Answers (1)

Matus Dubrava
Matus Dubrava

Reputation: 14502

The above code works just fine, the issue is that you forgot to set WORKDIR in your Dockerfile.

WORKDIR /code

which means that you are copying those package.json files into the root directory and node_modules will also be installed there (once the npm install is processed). Then you change workdir when you run the container and since you are using volumes, you will see some strange behavior (things are not exactly where they should be).

Also, while the trick with the additional volume works (node_modules inside of container are not obscured by the mount) there are drawbacks to this approach.

  1. You are creating new unnamed volume each time you run the container. If you don't take care of the old volumes, soon your system will be filled with a lot of dangling volumes.

  2. You are preventing node_modules syncing which is not exactly convenient during development. If you try to install some additional packages once the container is running, you will need to stop the container, build a new image and run it again because it is using the old node_modules which are created during build time.

I guess that this is a matter of taste but I prefer to sync local node_modules with the container via bind mount to avoid the above mentioned problems.

Upvotes: 2

Related Questions