How JavaScript works: introduction to PM2, Strongloop, and Forever + 4 tips for Production Process Managers

Ukpai Ugochi
SessionStack Blog
Published in
13 min readSep 23, 2021

This is post # 45 of the series, dedicated to exploring JavaScript and its building components. In the process of identifying and describing the core elements, we also share some rules of thumb we use when building SessionStack, a JavaScript tool for developers to identify, visualize, and reproduce web app bugs through pixel-perfect session replay.

The goal of every organization that builds software is to provide scalable products that deliver value to their customers. This means that the software has to be closely monitored so that the program runs smoothly and there’s no downtime. However, what happens when the software crashes during scaling or how developers can monitor their applications to ensure the guaranteed uptime and functional quality?

This is where production process managers come in. They are tools that allow developers to keep their processes or scripts alive. With production process managers your application will restart when there’s a failure or a crash. Production managers also make it easier to monitor applications properly as they provide logs on the state of the application.

In this article, we will be exploring the different production process managers, why they are necessary, and how to use them in a Node.js-based applications.

What are Production Process Managers

Production process managers are tools that run the application’s process continuously and ensure that it is always alive. It works as a daemon and runs the application’s process in the background.

A daemon runs as a background process while executing multitasks, therefore it is not in the direct control of an interactive user. For instance, for programs that are in direct control of an interactive user, closing the program window can stop the program from running. However, for production process managers, the user cannot stop the program from running simply by closing the program window. To stop production process managers from running, the developer will run a command to stop a single application or all applications connected to the process manager.

While production process managers are excellent with multitasking, they also perform system administration tasks such as modifying the environment, editing configurations, restarting applications at failure, etc. all this without downtime.

Why do you need a Process Manager

Process managers are necessary, especially for Node.js-based applications.

Hot reload

Node.js applications will stop once there’s an error in a process. This will cause downtime if it’s not noticed earlier. Sometimes, when a dependency is downloaded in a Node.js application, there’s a need to reload the application. Production process managers reload an application whenever there’s a change. It also reloads the application automatically whenever there’s a failure or crash to ensure there’s no downtime.

Configurations

Production process managers allow developers to configure the behavior unique to an application. These behavioral configurations of the application make managing and monitoring the application easy. For instance, to investigate the cause of an error properly, developers can specify a delay before an automatic reload triggered by a failure or crash for each application.

Multitasking

Production process managers are not only suitable in the production environment, but they can also be used in the development environment. Most times, managing multiple Node.js applications can become too difficult to handle. Production process managers work in the background making it excellent in handling multiple applications simultaneously.

Monitoring and management

Production process managers not only provide logs as a means of application monitoring, but it also gives developers access to key metrics of the application like memory and CPU usage.

Setting up a Node.js application

Node.js is an open-source server-side runtime environment for JavaScript. It is cross-platform, i.e runs on various environments, and is a very popular JavaScript runtime environment. In this section, we will be setting up a Node.js application as well as integrating production process managers into the application we have created.

Firstly, you’ll have to install Node.js on your local machine if you don’t have it installed already. Restart your local machine and confirm that Node.js is properly installed.

node — version

Next, create a folder in your machine for the Node.js application, name the folder myapp. In your terminal, navigate to myapp with cd myapp and execute npm init. Provide the information necessary and a package.json file will be created at the root of your project with the information you provided. Create a file in the root of your folder and name it index.js. This is the entry point of your application. Put the code below into the index.js file you just created:

Install express by running the command below in your terminal:

npm i express

Now, run node index.js to start your application. Navigate to http://localhost:3000/, and the page will display “This is Home Page.”.

Because our application isn’t connected to a production process manager, notice how the connection is lost if you shut down the terminal. Also, the application doesn’t affect recent changes made until you restart the application manually. Now, let’s connect the application we just created to production process managers.

Using Process Managers for a Node.js-based application

There are different production process managers for Node.js-based applications. Let’s explore the different process managers and how to use them.

PM2

PM2 is an advanced production process manager that can run on any script. This production process manager like other production process managers allows developers to keep their application alive forever and perform system administrative tasks without downtime. PM2 provides application management, load balancing, which allows multitasking, allowing developers to configure their applications to suit their needs.

To install PM2 in your Node.js application, run the command below in your terminal:

// Install with npmnpm install pm2 -g// Install with yarnyarn global add pm2

Notice how pm2 dependency has been added to your package.js file. Now, instead of running node index.js to start your application, run the command below to start your application with pm2:

pm2 start index.js

If we close the terminal, notice that our application is still running. Also, notice that the new changes you apply in your application are not reflected. This is because watching is disabled for the application. To turn on watching for the application, restart the application with watch by running the command below:

pm2 restart index.js — watch

Cluster mode

Running an application in pm2 with the cluster mode allows networked Node.js applications (http(s)/tcp/udp server) to scale across all CPUs available. Cluster mode increases the performance of an application depending on the number of CPUs available.

The image is from pm2 https://bit.ly/3lJlpxr

To run the application in cluster mode, execute the command below:

pm2 start index.js -i max

The -i flag is the cluster option whereas max instructs pm2 to detect the number of CPUs available and run as many as possible.

Persistent application -, what happens when your machine stops unexpectedly

The pm2 monit command allows developers to monitor their processes. To look at our application’s dashboard so that we can monitor it properly, run the command below in your terminal.

pm2 monit

To stop the application from running, execute the command below in your terminal.

pm2 stop index.js

However, notice how the application is still displayed on the pm2 table:

To remove the application from the pm2 table, run the command below:

pm2 delete index.js

However, what happens if your machine shuts down unexpectedly, how do you avoid downtime?

When you generate a startup script, PM2 will automatically restart at boot time. PM2 automatically generates and configures a startup script when you execute the pm2 startup command. To use the startup script, make sure your system has a supported init system. Here’s a list of the supported init systems:

The init systems are automatically detected by PM2 when you run the pm2 startup command. If you attempt to run the startup script without the init system, you’ll get an error:

Although PM2 has no built-in startup support for Windows, pm2-installer tends to fill in the void, allowing developers to use the startup command.

Configuration file

When managing multiple applications, it becomes difficult to pass configurations in the terminal. PM2 allows you to generate a simple JavaScript configuration file to manage and organize configurations.

To create a configuration file, run the command below:

pm2 init simple

This command will generate an ecosystem.config.js file at the root of your project. With the configuration file, you can start only one application by passing its name and the only flag:

pm2 start ecosystem.config.js — only index.js

Also, it is in the configuration file that the developer specifies the development and production variables:

This allows you to decide which environment you want to run by passing the name of the environment. For instance, if you want to run in the production environment, you’ll execute the command below:

pm2 start ecosystem.config.js — env production

Static serving and deployment with PM2

PM2 has a powerful deployment system that allows easy upgrading of applications in the production environment. First, you’ll add a deploy attribute to the ecosystem.config.js file. Here’s a simple deployment configuration.

Next, install PM2 in your remote server and provision the server. To provision the server, run the command below:

pm2 deploy production setup

After provisioning the server, run the command below to deploy your application:

pm2 deploy production

Also, while using PM2 in your local environment, you can host static files easily over http with the serve command.:

pm2 serve <path> <port>

If you don’t specify a path or port, the current folder will be used as the path while the default port 8080 will be used as port.

StrongLoop process manager

Strongloop process manager is another production process manager like PM2. However, strongloop process manager is a Node.js based process manager and can run only on Node.js based applications. While the strongloop process manager looks similar to PM2, they are different. For instance, PM2 allows the use of NGINX as a HTTP proxy for serving static files rapidly but the strongloop process manager does not. Let’s explore the strongloop process manager and its features.

Strongloop process manager can be connected to an application in your local machine or a remote environment.

Strongloop for remote use

You can install strongloop for use in a production environment using npm or with docker. To install strongloop with npm, run the command below:

npm install -g strong-pm

For Linux distributed systems that support upstart or systemd, it is better to install process managers as a service so that it can start when the system boots to aggregate logs properly, etc. To install strongloop as a service, run the command below:

Or, install strongloop with docker using the command below:

sudo sl-pm-install — driver docker

When you set up strongloop process manager to “Dockerize” apps deployed to it, your app will be turned into a Docker image and then run in a Docker container. If you don’t want to install anything, you can run PM2 from the docker hub. Run the command below to download the image, start a strongloop process manager container and create an upstart or systemd config file:

curl -sSL https://strong-pm.io/docker.sh | sudo /bin/sh

Next, build your application with slc build, then run the command below to deploy your application:

slc deploy http://your.remote.host

Now that you’ve deployed your application, you can check the status of your application by running the command below:

slc ctl status — control http://your.remote.host

Just like in PM2, the strongloop process manager allows you to change the cluster size on the remote host. By default, the strongloop process manager runs one process per CPU. However, you can choose to change the cluster size to suit your needs. For instance, you can change the cluster size of your remote host to two with the command below:

slc ctl — control http://your.remote.host set-size <app name> 2

When there are changes to your application’s source code, you can re-deploy your application by building your application and deploying it to the production host with the deploy command. This way, the strongloop process manager automatically performs a rolling restart of all processes, so you get zero downtime.

Strongloop for local use

Strongloop process manager can also be used in a local machine to monitor and keep your application alive. First, install strongloop into your local environment with the command below:

npm install -g strongloop

Next, start your application with slc start:

You can check the status of your application with the command below to confirm that it started successfully:

slc ctl status <app name>

Also, you can check the logs of your application with the log-dump command:

slc ctl log-dump <app name>

Forever

Forever is a command-line interface tool that keeps Node.js scripts running forever. Just like other process managers, forever runs Node.js scripts in the background as a daemon. Forever, just like PM2 can run other scripts that are not Node.js based. While Forever is a CLI tool, developers can choose to use this tool programmatically without the CLI by installing the forever-monitor.

Forever CLI

To install the forever tool and use the CLI, run the command below in your terminal:

npm install forever -g

Now, you can start your application with the command below:

forever start index.js

Just like other production process managers, you can create a config file and write app-specific configurations into the config file. For example, consider an application with a file structure below:

└── development.json└── package.json└── index.js

You can write app-specific configurations into the development.json file as shown below:

You can start this application by running the command below in your terminal:

forever start ./forever/development.json

Using Forever programmatically

With the Forever monitor, you can use forever from inside your code like other dependencies. First, install forever-monitor via npm with the command below.

npm install forever-monitor

Next, declare the dependency in your application like you would declare other dependencies:

var forever = require(‘forever-monitor’);

Now, you can create multiple processes to monitor your applications:

Below is a list of frequently used commands in Forever and their descriptions:

Tips for using production process managers

Production process managers are usually fast and robust, they allow you to manage your application efficiently. While we have explored how to use production process managers in a local machine, let’s look at the best practices for using production process managers in a production environment:

  1. Keep development and production as similar as possible. This is because a large change in production can break your application.
  2. Store configurations for the environment in the ecosystem.config.js file so that configurations that are meant for the development environment are not mixed with configurations for the production environment.
  3. Run admin/management tasks as one-off processes so that you don’t keep restarting your application. Only restart your application when necessary.
  4. Explicitly declare and isolate dependencies. For instance, you should turn off watching in your node-modules folder since it contains dependencies.
pm2 start env.js — watch — ignore-watch=”node_modules”

Conclusion

As an application’s server throws an error, it malfunctions and can cause downtime if not managed properly. With production process managers, developers monitor their applications as well as get key metrics about their apps.

Although some tools like nodemon can restart a Node.js application whenever a change in the file is noticed, they don’t offer restart on failure or other features a production process manager offers like multitasking and running in the background, etc.

The production process managers we have discussed in this article are the popular production process managers used in Node.js-based applications. Some of the other production process managers that can be used in Node.js based applications are supervisor and systemD.

Production process managers makes it much easier for products like SessionStack to be available as a service in the cloud with continuous availability. SessionStack collects behavioral data during customer journeys, allowing you to replay them as a video. Since SessionStack collects a large amount of behavioral data concurrently, production process managers are an important aspect of our stack that allows us to deliver a reliable and robust service.

There is a free trial if you’d like to give SessionStack a try.

SessionStack replaying a session

If you missed the previous chapters of the series, you can find them here:

--

--