Reloading code in a dockerized node.js app with docker-compose

The only difference between what I have and what you have is that I don't have the COPY directive in my Dockerfile. Try removing that and see if it works.

I also use nodemon to automatically restart the node server when the code changes:


I have seen the phrase "live reload" used to apply to two different types of reloading:

  1. killing & restarting the application when the code changes, and
  2. automatically reloading HTML & assets on a client browser when the code changes.

Based on your question, I think you're referring to the first type, so the answer that follows addresses that.


The problem here is one of context.

Remember that the docker container is isolated from your host - specifically, the processes running in the container are distinct from (and generally cannot interact with) processes running on the host. In your case, you have chosen to mount a host directory in the container, but that's just the filesystem, not the processes.

Think through what your Docker image does when you instantiate a new container: it runs node index.js in the WORKDIR. Where is the code to stop it and restart it when the code changes? Presumably it's running in a process on the host. This means that it cannot touch the node process running in the container (because it's isolated).

Now, you haven't mentioned what method you're using to handle the live reloading, but that shouldn't make too much of a difference. They all basically work the same way: on a change to the application code, kill the existing process and start a new one.

To solve this, you have two options:

  1. run the "live reloading" code inside the container, or
  2. run your development code outside the container

For the first, you could follow @MarkS's suggestion and use nodemon. This should be as simple as replacing

CMD ["node", "index.js"]

in your Dockerfile with

CMD ["nodemon", "index.js"]

provided, of course, that you have nodemon properly installed in the image.

The alternative, and this is what I do, is to run the code on the host outside the Docker environment during development, and then package it up in an image at deployment. This solves two problems:

  1. the problem you're running into with isolated node processes, and
  2. permission problems.

Remember that apps running in Docker are run as root. This means that if your app creates files, they're going to be owned by root. I tried developing in a Docker environment, but got frustrated by problems where, for example, I wanted to delete a file created by the app and had to sudo (sign in as root) just to clean up stuff.