I’m currently working on a Node.js application that runs within a Docker container. I wanted the container to auto-restart whenever it crashed and I found out that this task could be accomplished with tools like PM2 and forever.
I decided to give PM2 a try. Unfortunately, it kept restarting the container in an endless loop. Through my
research, I discovered that
pm2 was not meant to run within Docker and that
pm2-runtime should be used instead.
More details can be found on PM2’s official website.
That is, instead of calling:
pm2 start app.js
One should call:
pm2-runtime start app.js
pm2-runtime stopped the restart loop. However, I realized that PM2 was much more than an
auto-restart script and offered many capabilities that appeared to overlap with Docker’s. It didn’t feel right.
My suspicions were confirmed when I stumbled upon this article on Docker’s official blog.
Here’s the relevant snippet:
Except for local development, don’t wrap your node startup commands with anything. Don’t use npm, nodemon, etc. Have your Dockerfile CMD be something like
[“node”, “file-to-start.js”]and you’ll have an easier time managing and replacing your containers.
Nodemon and other “file watchers” are necessary in development, but one big win for adopting Docker in your Node.js apps is that Docker takes over the job of what we used to use pm2, nodemon, forever, and systemd for on servers. (emphasis mine)
By launching my application directly with Node, Docker was now able to auto-restart the container whenever it crashed.
All I had to do was to specify a restart policy
docker-compose.yml file. I settled on
restart: always. Assuming your container is named
docker-compose.yml file would thus look like this:
1... 2services: 3 container-example: 4 ... 5 restart: always