Skip to content

Node.js & PM2

How to manage Node.js applications

When you have a Node.js app, you need to manage it on your server.

Unlike PHP app, which just need to have NGINX/Apache configuration, a Node.js app can have two production options : generate static project or launch server. With the first, you compile your project into html, js and css files, and you can host it with a basic NGINX/Apache config like PHP app.

It's easy but if you want to update infos of your app with a back-office via an API, infos won't update on your app because it's static app (you will have to re generate your app each time...). The solution is the second option, host a server, it will update infos of your app if you change it with a back-office. To manage a Node.js app like this, you need a manager to keep live your app and PM2 is here for it.

INFO

In this example, we take a project works Express, an old but still used Node.js framework. You can find it here ewilan-riviere/express-starter.

sh
git clone https://gitlab.com/ewilan-riviere/express-starter.git /var/www/express-starter

Create NGINX configuration

You need to have a domain and NGINX. The configuration of Nginx is light but necessary to allow PM2 to serve it on this domain with reverse proxy.

nginx
server {
  server_name domain.com;

  location / {
    include proxy_params;
    proxy_pass http://localhost:3000;
  }
}
/etc/nginx/conf.d/domain.com.conf

With this config, server_name is the domain to host project and proxy_pass have a specific port will be used by PM2 (use one specific port by app like 3000, 3001, 3002...).

sh
sudo nginx -t
output

If you have this output, everything is fine, otherwise you will have some infos to fix it:

sh
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
output

And reload NGINX to apply changes:

sh
sudo service nginx reload

Install PM2

INFO

You have to install Node.js before PM2, you can find a guide here: Node.js

Use NPM globally:

sh
npm install pm2@latest -g

Ecosystem

PM2 is now available on your server, you can use it on different ways but here, we use ecosystem solution. With this, it's easy to maintain a lot of Node.js app with just JSON. You have just to create ecosystem.config.js anywhere on your server:

sh
vim ~/ecosystem.config.js
js
module.exports = {
  apps: [
    {
      name: "express-starter",
      script: "npm",
      cwd: "/var/www/express-starter",
      args: "start",
      env: {
        PORT: 3000, // same port as in Nginx config
      },
    },
  ],
};
~/ecosystem.config.js
  • name is PM2 id for this app
  • script is the package manager used by PM2 to serve this app
  • cwd is the absolute path of your project
  • args is the action of script from package.json for classic app and env define port for this app (you can't serve multiple app on same port).
  • PORT is the port used by your app

INFO

start script is "start": "node app.js" in example of express-starter app.

In this example, express-starter is a Node.js app with theses scripts into package.json:

json
{
  // ...
  "scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js"
  },
  // ...
}
/var/www/express-starter/package.json

Start PM2

Now, you can start your app with PM2:

sh
pm2 start ~/ecosystem.config.js

Save this config to restart automatically apps when server reboot:

sh
pm2 save

And list apps with this command:

sh
pm2 ls

You have to see this output:

sh
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
 id name mode status cpu memory
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
 0 express-starter fork 7 online 0.3% 47.2mb
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘

If everything is fine, your app is online and you can access to it via server_name define in Nginx config.

Cheatsheet

List apps with status

sh
pm2 ls

Save config

sh
pm2 save

Start ecosystem

sh
pm2 start ~/ecosystem.config.js

Kill all apps

sh
pm2 kill

Start app

sh
pm2 start {id}

Start all apps

sh
pm2 start all

Stop app

sh
pm2 stop {id}

Stop all apps

sh
pm2 stop all

MIT License