This article was originally published a day earlier at https://maximorlov.com/start-node-js-in-production/
You've built a Node.js app and now it's ready to face the world. That means you'll have to deploy it to a production environment.
How do you properly start a Node.js application in production? What are the best practices, and how is it different from development?
Don't let these questions stop you.
What if you could deploy with confidence knowing that your application is always up and running?
Learn why process managers are an indispensable tool in production environments and which are the three most popular ones.
But first, let's talk about about starting an application in the foreground vs in the background and what happens when it crashes.
Foreground vs background processes
During development you probably start your Node.js server by opening up the terminal and typing node index.js
(or whatever file is the starting point of your application). If this command lives in the package.json file, you run it with NPM using npm start
.
When you press CTRL+C or close the terminal, the application exits as well. That's usually what we want during development, but not in production.
In a production environment, an application should keep running beyond the lifecycle of our terminal or SSH connection.
When you work on an application locally, you start it as a foreground process. In the foreground, your keyboard input is directed to the process. That's why when you hit CTRL+C, it sends a SIGINT
signal and stops the application. What we want instead is to start the application in the background.
To start an application in the background, you simply append &
at the end of the command. Using the example from earlier, node index.js &
will start your Node.js server in the background which will stay up even after you close the terminal or SSH connection to your production server.
What happens when your application crashes?
Applications inevitably crash in production due to one of many reasons — a memory leak, an uncaught promise rejections or an infinite loop. With your application now running independently, what happens if it crashes or stops responding?
To solve this, we would need another process that manages our application and is responsible for restarting it on such occasions. That's exactly what process managers do.
A process manager starts your application as a background process and will restart it when it crashes. It can also automatically start your application on system startup if you want.
Keeping your application alive is by far the most important feature of process managers.
The three most used process managers by Node.js developers are PM2, Docker and Systemd. Depending on your situation and purpose, you might be better off using one over the other. All three are used by many applications in production and you can't go wrong with either of them.
Process managers for Node.js applications
PM2
PM2 is the most popular process manager in the Node.js community. The codebase of PM2 is written in JavaScript and is designed specifically for Node.js applications. It has a nice UI and offers cluster mode with load balancing out of the box. The latter makes it easy to scale Node.js by using multiple CPU cores.
To get started with PM2, I recommend following their quick start guide. When you want to learn how to use a new library or tool, the official documentation is always a good place to start.
When I'm deploying an application that doesn't live in a container, PM2 is my go-to process manager. It's easy to use which allows me to focus on app development.
Docker
If you're using Docker to containerise and deploy your application, you can use the built-in process management features. With the Docker CLI you can configure the container to automatically restart when your application crashes.
You can also define a HEALTHCHECK
in your Dockerfile. Docker will use it to determine if your application is healthy. Health checks are useful when your application could be running, but unable to handle new requests because it's stuck in an infinite loop for example.
When I'm deploying a Node.js application with Docker I don't use PM2 as most of its benefits are replaced by Docker.
Systemd
Every operating system comes with a default process manager. For most popular Linux distributions, that's systemd.
You can view systemd as the main process manager. If you're using a process manager such as PM2 or Docker, they themselves are managed by systemd. Systemd is the first process started by the Linux kernel on system startup, and it's in charge of starting all other processes.
Systemd is a bit daunting to learn if you're unfamiliar with system administration. Nonetheless, using systemd is a great way to learn about DevOps and becoming more comfortable using Linux. This old but still relevant article shows you how to use systemd with Node.js.
Conclusion
We've talked about the difference between running a process in the foreground vs in the background. In production environments we want our applications to keep running after we close the terminal which is why we run them in the background.
Applications will inevitably crash and a process manager makes sure to restart them when they do. They keep your application alive and they can also automatically start the application on system startup.
PM2 is the most used process manager in the Node.js community and it is easy to use. If your application lives in a container, Docker has built-in process management features. If you want to learn DevOps and want to be more comfortable with Linux then using systemd is a great choice.
There's more to running a production Node.js appliction besides automatic restarts – you have to add useful logs and set up monitoring & alerting amongst other things. You don't have to learn those before deploying your application.
Get your application live, show the world what you've built and worry about the rest later.
Happy shipping! 🚀
Write clean code. Stay ahead of the curve.
Every other Tuesday, I share tips on how to build robust Node.js applications. Join a community of developers committed to advancing their careers and gain the knowledge & skills you need to succeed.
Top comments (7)
Thanks!
Pleasure
Nice Post ! . I like PM2 very good to Node.js Applications
While I do see a clear use case for docker/kubernetes to have such a feature built-in, I can not understand why you would rely on an node.js specific process manager, if you can just create a systemd unit.
It always seems as 'Do I really need to set up Docker?', lol
I guess you have to get good at it and find the right use cases for it, to grasp it's power xdd
Docker does have a steep learning curve, but once you learn a few key things (writing a basic Dockerfile, port forwarding, volume mounts) it isn't too bad and you can accomplish most tasks!
I would much rather put in the investment up-front in setting up Docker than getting bit 6 months down the road with nasty bug when there is a subtle difference between how node behaves on my Mac vs the Linux machine it is running on in the cloud!