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.
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
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.
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.
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.
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.
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.
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! 🚀