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
Switching from pm2
to 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
in my docker-compose.yml
file. I settled on restart: always
. Assuming your container is named container-example
,
your docker-compose.yml
file would thus look like this:
1...
2services:
3 container-example:
4 ...
5 restart: always