NodeJS: Making docker-compose Volumes Ignore the node_modules Directory
How to keep your node_modules from disappearing when you map your app volumes
Code snippets can be found at the bottom of the article.
Problem
If you use Docker, you probably also use Docker Compose. Which means you map your app volume to the container volume if you are doing any local development.
But, when you do this, your local (and empty) node_modules folder will overwrite the container node_modules folder.
The fix then is to install your node_modules on thedocker-compose build
command, instead of docker-compose up
, and telling DockerCompose to not overwrite the node_modules directory.
Solution
A workaround
As a workaround, you can doCMD npm install && npm run dev
.
The problem with that approach is:
- It slows down the
docker-compose up
command - It makes Docker Hyperkit take up a lot more CPU than it needs
A better solution
Have docker install node_modules on docker-compose build
and run the app on docker-compose up
.
Folder structure:
docker-compose.yml
:
Dockerfile
:
Note — we need to copy
package.json
first because volume mapping happens on thedocker-compose up
command, and so this file does not exist onbuild
yet
Common errors
- If you had already built the containers and installed packages into the node_modules directory, it’s best to clean up before trying this by removing all your containers and images related to the project
# will remove everything
docker container rm -f $(docker container ls -qa)
docker image rm -f $(docker image ls -q)
2. If you install a new module, you can either
i. ssh into the container and install it directly
# remember, $CONTAINER_FOLDER is the name of this container
docker exec -it $CONTAINER_FOLDER npm install $YOUR_NEW_NPM_MODULE
ii. install it on your system (which updates packages.json) and rebuild the image
npm install $YOUR_NEW_NPM_MODULE# remove the image where the new module is installed
docker image rm -f $CONTAINER_FOLDER# rebuild, while making sure it doesn't use the internal cache
docker-compose build --no-cache
docker-compose up