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:

  1. It slows down the docker-compose up command
  2. 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 the docker-compose up command, and so this file does not exist on build yet

Common errors

  1. 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

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store