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
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.
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
, thenode_modules
that were installed in the Docker container withdocker-compose build
, are overridden by the application's source code (./app/frontend:/usr/src/app
). I don't havenode_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