Process Manager 2 with Node.js

If you work with Node.js applications often, you might be familiar with the default script npm start, which will generally run your server directly. This may seem like it is enough initially, but in the real world when your app encounters an error, your app may crash for everyone.

This is where PM2 comes in. PM2 or Process Manager 2 is a versatile process manager written in Node.js.

This article will cover PM2, its advantages, how to use it, and why PM2 is popular amongst organizations.

1. Prerequisites

To follow this tutorial along – the reader should have the following:

  • Have Node.js installed in your system. To install Node.js safely in your system visit the official documentation via this link.
  • Some prior knowledge about Node.js and you should be familiar with Linux commands and operating system.

Before discussing PM2, we will first start with the root of its existence i.e., Node.js, so as to have a clear understanding of PM2.

2. What is Node.js?

Node.js is an open-source, cross-platform, JavaScript runtime environment that executes JavaScript code outside of a web browser and whose architecture is based on single-threaded non-blocking concurrent input/output. It is a lightweight web framework and very friendly to beginners.

Node.js is written in C, C++, JavaScript, and it is built on the open-source V8 JavaScript engine. As V8 supports latest features in JavaScript, they are added into Node.js.

V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++. It is used in Chrome and in Node.js, among other browsers. To know more about it you can visit to the official documentation via this link.

It also has access to a C++ library called Libuv which provides Node.js to have access to the OS, filesystem, and to the event, loop to manage asynchronous operations.

3. Why Node.js?

Node.js uses an “event-driven, non-blocking I/O model”. This means that Node.js is built well to handle asynchronous JavaScript tasks to perform many asynchronous activities. Activities such as reading or writing to the file system, handling connections to database servers, or handling requests as a web server, etc.

To handle asynchronous tasks, Node.js uses a callback-based system. Node.js functions or methods that might have to do some asynchronous actions takes a callback function.

For example:

const fs = require("fs");

fs.readFile("./hello.txt", (error, data) => {
  if (error) throw error;
  console.log(data);
});

In this example, we are using Node.js’s built-in fs (File System) module to read a hello.txt file. The callback function is called after the file-reading operation is completed. If an error occurs, it will be passed as an error and thrown.

4. Advantages of Node.js

It offers high performance in real-time

Web applications written in Node.js takes a lot of advantage from its ability to multitask. Unlike other languages, its single-threaded, event-driven architecture processes multiple concurrent requests efficiently.

Easy scalability for modern applications

With a growing demands for efficient backend, tons of MNC ‘s like Netflix, Walmart, Google, etc., have regarded Node.js as a valuable solution for scalability.

Offers community support to simplify development

With millions of developers contributing actively to the Node.js community, you can get extensive support from experts across the world to solve even the most peculiar development problems.

For instance, NPM, a package manager for JavaScript, is the biggest package manager repository in the world. It offers numerous tools and libraries available readily for you to use in your project.

Node.js reduces loading time by quick caching

Node.js made it really easy for developers to reduce task workload and re-execution of code with its caching module. So every time the any module of your web application gets a request, it gets cached in the app ‘s memory which is real efficient for frequently visited websites.

Node.js allows you to use Microservices that lets you segregate your application into smaller parts.

5. What is PM2?

PM2 is a free open source, efficient, and cross-platform production-level process manager for Node.js with a built-in load balancer.

It works on Linux, MacOS as well as Windows. It supports real time app monitoring, efficient management of micro-services and shutdown of apps.

It keeps your applications “alive forever” with auto restarts that can be enabled to start the app at system boot, thus allowing for higher availability configurations.

6. Why PM2?

  • Restarting after crashes: PM2 allows us to keep processes running endlessly, until we shut down our system.
  • Monitoring and managing processes remotely: Web portals allows you to keep track of remote processes and manage them at any time.
  • Wide support: PM2 isn’t limited to just to Node.js processes, that’s right. It can be used to manage NGINX servers, Apache servers, etc.
  • Restart-Persistence: PM2 remember all your processes and restart them after a system boot.

Let’s take an example to really understand all this,

Assume you have a microservice in Node.js running on port 8000.

const http = require("http");

const hostname = "192.162.93.11";
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader("Content-Type", "text/plain");
  res.end("This is the Main App!\n");
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

The code above will run on the server after executing the Node.js server.js command but what if something make this app crash. We need to restart it manually by executing the same command line.

Since it is a small code snippet, it can be done easily. Suppose we have an enterprise-level codebase, then this would be terrible and time-consuming.

Here, PM2 comes to the rescue by restarting the Node.js API automatically. You will not have to run your application as root therefore, your application will be protected.

Your application will restart if it crashes, and it will keep track of the log for unhandled exceptions. Your app will restart when the server starts again.

7. Installation of PM2

If you haven’t installed Node.js you can safely install it in your system visit the official documentation via this link or if you want to save some time so you can also go to this link this link.

After successfully installing Node.js and npm i.e., node package manager, the first thing we need to do is to install PM2 globally on your system:

npm i -g pm2

If you prefer yarn as your package manager then,

sudo yarn global add pm2

8. Starting and configuring PM2

To start a process under PM2, all you need to do is run pm2 start <app> to make your application managed by PM2.

PM2 will output something like this for Windows users:

[PM2] Starting C:\Users\moose\app.js in fork_mode (1 instance)
[PM2] Done.
┌──────────┬────┬
│ App name │ id │
├──────────┼────|
│ app      │ 0  │
└──────────┴────|

For Linux and Mac users, the command and output are a little different:

sudo pm2 start example.js

[PM2] Spawning PM2 daemon
[PM2] PM2 Successfully daemonized
[PM2] Starting example.js in fork_mode (1 instance)
[PM2] Done.
┌─────────┬──┬────┬────┬──────┬───────┬──────┬─────────┬──────────┐
│ App name│id│mode│pid │status│restart│uptime│memory   │ watching │
├─────────┼──┼────┼────┼──────┼───────┼──────┼─────────┼──────────┤
│ example │0 │fork│3221│online│0      │5s    │15.276 MB│ disabled │
└─────────┴──┴────┴────┴──────┴───────┴──────┴─────────┴──────────┘
 Use `pm2 show <id|name>` to get more details about an app

The output should be similar to this. The rest of the commands will have sudo in it. Just remove sudo from each command, then it should be the same for Windows users.

This can be enhanced even more after starting an app by using the restart subcommand with the name flag followed by the name of your app.

sudo pm2 restart old-app-name --name new-app-name

PM2 will automatically restart applications running under it, but we will need to do some additional steps if we want PM2 to launch our application on system startup.

In order to do that, we will use PM2’s startup command, which is:

sudo pm2 startup systemd

The command above will generate a script that your server will use to initiate PM2 ‘s specific app processes on system boot.

If successful, you should see an output similar to this:

[PM2] Generating system init script in  /etc/systemd/system/pm2.service
[PM2] Making script booting at startup...
[PM2] -systemd- Using the command:
      su root -c "pm2 dump && pm2 kill" && su root -c "systemctl daemon-reload && systemctl enable pm2 && systemctl start pm2"
[PM2] Dumping processes
[PM2] Stopping PM2...
[PM2] All processes have been stopped and deleted
[PM2] PM2 stopped
[PM2] Done.

Next, we want to let PM2 know which apps to start on boot. We can do this by saving the current process list, which in our case would only be our “example” app.

To save the current process list, run:

sudo pm2 save

[PM2] Saving current process list...
[PM2] Successfully saved in /home/deployer/.pm2/dump.pm2

That’s it! Now PM2 is configured and will automatically launch the applications specified in the saved process list on every reboot.

9. PM2 Cluster Mode

The cluster mode allows networked Node.js applications to be scaled across in parallel across all CPUs available, without any code updates.

This increases performance and reliability of your applications, depending on the number of CPUs available at a given time.

To enable the cluster mode, just pass the -i option:

sudo pm2 start server.js -i max

max means that PM2 will auto-detect the number of available CPUs and run as many processes as possible.

10. Advantages of PM2

Built-in clustering

PM2 handles all of the logic for you internally so you don’t have to change anything in your code.

Scaling your cluster in realtime

You can scale your cluster anytime by running pm2 scale <app name> <n> where <n> can be a number for which the cluster can scale up or down.

Updating your apps in production with zero downtime

pm2 reload <app name> feature will restart your workers one by one, and each worker will wait till the new one has done its job before killing the old one.

This way, your server keeps on running even when you are deploying the new batch straight to production.

Apps will stay alive

If any of your workers happens to die, PM2 will restart them immediately so you don’t have to worry about that either.

11. Log Management in PM2

PM2 has built-in log management. It collects log data from your applications and jots it down into a single file.

You can even view these logs in real-time to see what’s going on under the hood with your application. Log Management from PM2 comes with log rotation as well, which is important, especially if your app gives verbose output logs regularly.

These are some basic command which you can use to handle the logs of your app:

  • pm2 logs – Outputs logs from all running applications.
  • pm2 logs app – Outputs logs from only the app application.
  • pm2 flush – Flushes all log data, freeing up disk space.

The most important thing to do is to enable log rotation.

By doing this, PM2 will be able to split one big chunk of the log file into many smaller files that they are easier to process by PM2.

To do this, run the following command:

pm2 install pm2-logrotate 

12. Conclusion

PM2 allows us to focus on building amazing applications without worrying about the massive overhead that is required to keep an application up and running and it makes life so much easier when we work with complex data in Node.

This is only a small snippet of what you can do with PM2, but you have to try it out yourself to see the full power that PM2 has to offer.

To find more information about PM2 check out the official docs via this link.

I hope you enjoyed reading this article as much as I enjoyed writing it.

Happy coding.

Related posts:

Getting Started with Json Web Auth using Angular 11 and Node.js
How To Build A CLI Tool With Node.js And PhantomJS
Open-source packages & Code Security using NPM
Introduction to Express.js
Introduction to the Koa.js Framework
How To Build and Test a Node.js REST API with Express on Ubuntu 18.04
Getting Started with Strapi API CMS
Writing A Multiplayer Text Adventure Engine In Node.js: Adding Chat Into Our Game (Part 4)
How to use CORS in Node.js with Express
Session Management in Node.js using ExpressJS and Express Session
Node.js - Frontend or Backend?
Getting Started with Node.js 15
Building A Real-Time Retrospective Board With Video Chat
Introduction to Job Scheduling in Node.js
The History of Node.js
How to Implement Caching using Adonis.js 5
Choosing Between NPM and Yarn
Using Slack To Monitor Your App
Getting Started with EJS Templating Engine
Uploading Images to Cloudinary using Node.js
How to Create a Simple REST API using TypeScript and Node.js
Optimizing Critical-Path Performance With Express Server And Handlebars
Implementing Caching in Node.js using Redis
An Absolute Beginner Guide to Node Package Manager
Debugging a Node.js Application running in a Docker Container
Analyzing Your Company’s Social Media Presence With IBM Watson And Node.js
Building a RESTful Web API in Node.js using PostgresSQL and Express
Getting Started with Node.js Worker Thread
How to Consume a Co-operative Bank API using Node.js
Debugging a Node.js app in VS Code
MySQL with Node.js
Getting Started with Node.js Event Emitter