Getting Docker, Node and NPM to play nice

Docker is an incredible tool for managing both production workflows as well as development workflows. Unfortunately, the most common pattern for doing development work using docker (mapping your source code folder as a volume), wreaks havoc on Node.

Node and NPM, by default, install all of the dependencies in the node_modules directory in the root directory of your project. When you, for development purposes, share that directory between your VM and your main computer’s file system you can wind up with a ton of permissions errors and failed dependency installations or lookups.

It doesn’t have to be this way! Though it took me a while to figure out the right incantations and settings to make it all work, the resulting thing was simple. You can set a “installation prefix” when you use npm to install dependencies, and you can set a NODE_PATH to include that prefixed installation directory. This way, your dependencies live in a directory that isn’t shared between your desktop and docker environments, and you can easily develop your node projects using docker and docker-compose to manage your environments.

An example Dockerfile uses this technique:

FROM node:5.8.0
# Optional: nodemon gives you superpowers to automatically restart
# your server whenever a file changes:
RUN npm install -g nodemon
# Make directories to store the dependencies and the application code:
RUN mkdir -p /package
RUN mkdir -p /application
WORKDIR /application
# Set up the basics:
ENV PORT 8080
EXPOSE 8080
# Tell node where to find dependencies (they are not installed in the
# normal location
ENV NODE_PATH /package/node_modules
COPY package.json /package
RUN npm install --prefix /package
# Copy the application
COPY . /application
# By default, run the application with node:
CMD [ "node","index.js" ]

A more complete docker-based development environment for node is available here: