1

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

sunsets
  • 401
  • 5
  • 23
  • you set path `/code ` in run command while `/ROOT` in docker-compose? – Adiii Jul 30 '20 at 04:49
  • @Adiii I thought the name either code or ROOT doesn't matter. isn't it? Updated) I've changed `/code` into `/ROOT` but it still doesn't work. – sunsets Jul 30 '20 at 04:55
  • I would delete all of the `docker run -v` and Compose `volumes:` options. Your application code and `node_modules` trees are built into the image already, so you don't need to provide them separately. – David Maze Jul 30 '20 at 11:59
  • @DavidMaze That's right. I found it out now and ended up resolving my obscure concepts. – sunsets Jul 31 '20 at 02:41

1 Answers1

2

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.

Matus Dubrava
  • 13,637
  • 2
  • 38
  • 54
  • Really appreciated and it works by your trick solution you said. I don't exactly understand `to sync local node_modules with the container via bind mount to avoid the above mentioned problem.` Could you tell me about it more or let me know ideas or links? – sunsets Jul 30 '20 at 08:32
  • It just means that I install `node_modules` locally and let them obscure the ones in the container with the rest of the files using the bind mount that you are currently using `./:/ROOT/`, but adding no additional volumes. – Matus Dubrava Jul 30 '20 at 08:39
  • then I have to deal with changes of huge node_modules on git or etc. What do you think of that? – sunsets Jul 30 '20 at 08:42
  • Not sure what you mean by that, you don't need to push node_modules to git. You just need to run `npm install` locally to create node_modules the same way you are doing it in a container. Of course, this is not the way you want to handle it in a production but we are talking about development since you wouldn't be using bind mounts like this at all in production. – Matus Dubrava Jul 30 '20 at 09:14
  • I'm confused. Why can't you use using bind mounts like that in production? Is this because of drawbacks you mentioned above? – sunsets Jul 30 '20 at 09:58
  • No, it is because there is no reason to do that. This particular approach that we are discussing here has only one purpose and that is to speed up development process by not having to rebuild the image every time you change a file (so that you can use tools such as `nodemon` etc.). Production images should be self contained. You definitely don't want to change a line of code in a live container that is running in a production therefore you don't need this at all. – Matus Dubrava Jul 30 '20 at 10:04
  • I understood. Thank you @Matus Dubrava – sunsets Jul 31 '20 at 01:55