Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker and node_modules - put them in a layer, or a volume?

I'm planning a docker dev environment and doubtful whether running npm install as a cached layer is a good idea.

I understand that there are ways to optimize dockerfiles to avoid rebuilding node_modules unless package.json changes, however I don't want to completely rebuild node_modules every time package.json changes either. A fresh npm install takes over 5 minutes for us, and changes to package.json happen reasonably frequently. For someone reviewing pull requests and switching branches quite often, they could have to suffer through an infuriating amount of 5 minute npm installs each day.

Wouldn't it be better in cases like mine to somehow install node_modules into a volume so that it persists across builds, and small changes to package.json don't result in the entire dependency tree being rebuilt?

like image 397
rgareth Avatar asked Dec 24 '14 21:12

rgareth


People also ask

What is the difference between Docker image and layer?

An image is a file that represents a packaged application with all the dependencies needed to run correctly. In other words, we could say that a Docker image is like a Java class. Images are built as a series of layers. Layers are assembled on top of one another.

Why do we use volumes in Docker?

Volumes are the preferred mechanism for persisting data generated by and used by Docker containers. While bind mounts are dependent on the directory structure and OS of the host machine, volumes are completely managed by Docker.

What are the two types of Docker volumes?

Docker volumes are used to persist data from within a Docker container. There are a few different types of Docker volumes: host, anonymous, and, named.


1 Answers

Yes. Don't rebuild node_modules over and over again. Just stick them in a data container and mount it read only. You can have a central process rebuild node_modules now and then.

As an added benefit, you get a much more predictable build because you can enforce that everyone uses the same node modules. This is critical if you want to be sure that you actually test the same thing that you're planning to put in production.

Something like this (untested!):

docker build -t my/module-container - <<END_DOCKERFILE
FROM busybox
RUN mkdir -p /usr/local/node
VOLUME /usr/local/node
END_DOCKERFILE

docker run --name=module-container my/module-container

docker run --rm --volumes-from=module-container \
    -v package.json:/usr/local/node/package.json \
    /bin/bash -c "cd /usr/local/node; npm install"

By now, the data container module-container will contain the modules specified by package.json in /usr/local/node/node_modules. It should now be possible to mount it in the production containers using --volume-from=module-container.

like image 186
mzedeler Avatar answered Oct 17 '22 17:10

mzedeler