Install node_modules inside Docker container and synchronize them with host


Install node_modules inside Docker container and synchronize them with host



I have the problem with installing node_modules inside the Docker container and synchronize them with the host. My Docker's version is 18.03.1-ce, build 9ee9f40 and Docker Compose's version is 1.21.2, build a133471.


node_modules


18.03.1-ce, build 9ee9f40


1.21.2, build a133471



My docker-compsose.yml looks like:


docker-compsose.yml


# Frontend Container.
frontend:
build: ./app/frontend
volumes:
- ./app/frontend:/usr/src/app
- frontend-node-modules:/usr/src/app/node_modules
ports:
- 3000:3000
environment:
NODE_ENV: ${ENV}
command: npm start

# Define all the external volumes.
volumes:
frontend-node-modules: ~



My Dockerfile:


Dockerfile


# Set the base image.
FROM node:10

# Create and define the working directory.
RUN mkdir /usr/src/app
WORKDIR /usr/src/app

# Install the application's dependencies.
COPY package.json ./
COPY package-lock.json ./
RUN npm install



The trick with the external volume is described in a lot of blog posts and Stack Overflow answers. For example, this one.



The application works great. The source code is synchronized. The hot reloading works great too.



The only problem that I have is that node_modules folder is empty on the host. Is it possible to synchronize the node_modules folder that is inside Docker container with the host?


node_modules


node_modules



I've already read these answers:



Unfortunately, they didn't help me a lot. I don't like the first one, because I don't want to run npm install on my host because of the possible cross-platform issues (e.g. the host is Windows or Mac and the Docker container is Debian 8 or Ubuntu 16.04). The second one is not good for me too, because I'd like to run npm install in my Dockerfile instead of running it after the Docker container is started.


npm install


npm install


Dockerfile



Also, I've found this blog post. The author tries to solve the same problem I've faced with. The problem is that node_modules won't be synchronized because we're just copying them from the Docker container to the host.


node_modules



I'd like my node_modules inside the Docker container to be synchronized with the host. Please, take into account that I want:


node_modules


node_modules


node_modules


node_modules



I need to have node_modules on the host, because:


node_modules


node_modules


devDependencies


eslint


prettier


devDependencies



Thanks in advance.




2 Answers
2



There's three things going on here:


docker build


docker-compose build


/usr/src/app/node_modules


docker-compose up


volumes: ['./app/frontend:/usr/src/app']


/usr/src/app


volumes: ['frontend-node-modules:/usr/src/app/node_modules']


node_modules



If you were to launch another container and attach the named volume to it, I expect you'd see the node_modules tree there. For what you're describing you just don't want the named volume: delete the second line from the volumes: block and the volumes: section at the end of the docker-compose.yml file.


node_modules


volumes:


volumes:


docker-compose.yml





Thanks for your answer. I have removed those two lines. After that, I have the same issue which was described here. When I am running docker-compose up, the node_modules that were installed in the Docker container with docker-compose build, are overridden by the application's source code (./app/frontend:/usr/src/app). I don't have node_modules on the host and because of this, I'm getting an error inside the container (e.i. node_modules don't exist).
– Vladyslav Turak
Jun 29 at 11:21


docker-compose up


node_modules


docker-compose build


./app/frontend:/usr/src/app


node_modules


node_modules





Yes, that's correct, that is in fact how it works: the mounted volume / host directory hides what was in the image. Docker won't automatically copy things from an image to a host-path volume ever. You could run npm install or yarn install on your host directory before launching the container, or change your command to something like npm install && npm start.
– David Maze
Jun 29 at 12:38


npm install


yarn install


npm install && npm start





I got it. The problem is that I wouldn't like to run npm install on my host machine because of the possible cross-platform issues. node_modules installed on the host machine don't always work properly inside the Docker container. There could be a lot of problems such as different environments, different NPM or Node.js versions (e.g. we run npm install on Mac with Node.js 8.11.3 and NPM 5.6.0 and mount the volume to the Ubuntu 16.04 Docker container with Node.js 10.5.0 and NPM 6.1.0). The application won't work. As I understand, it is not possible to achieve what I want?
– Vladyslav Turak
Jun 29 at 13:23


npm install


node_modules


NPM


Node.js


npm install


Node.js 8.11.3


NPM 5.6.0


Node.js 10.5.0


NPM 6.1.0





For example, node-sass is a binary and it really matters where it was compiled. If the environments differ, we will get an error. Read more here.
– Vladyslav Turak
Jun 29 at 13:27




I wouldn't suggest overlapping volumes, although I haven't seen any official docs ban it, I've had some issues with it in the past. How I do it is:



The above might be achieved by shortening your compose file a bit:


frontend:
build: ./app/frontend
volumes:
- ./app/frontend:/usr/src/app
ports:
- 3000:3000
environment:
NODE_ENV: ${ENV}
command: npm start



That means you might need two Dockerfiles - one for local development and one for deploying a fat image with all the application dist files layered inside.



That said, consider a development Dockerfile:


FROM node:10
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
RUN npm install



The above makes the application create a full node_modules installation and map it to your host location, while the docker-compose specified command would start your application off.





Thanks for the answer. It seems like I will have the same problem as I've described here, won't I?
– Vladyslav Turak
Jun 29 at 11:27






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Opening a url is failing in Swift

Export result set on Dbeaver to CSV