PM2

Original link: https://editor.leonh.space/2023/pm2/

PM2 is an app server for Node.js, just like Uvicorn or Gunicorn for Python, Passenger for Ruby, and PHP-FPM for PHP.

These app servers are responsible for scheduling and supervising apps. The apps here are the projects or programs we write. The app server is usually used as a system service. When it runs, it will also call our app, and decide how many times to open depending on the load. Only the app program is used to digest the load, and it is also responsible for restarting the app when the app fails. The app server plays an important role in affecting the stable service of an app in a formal environment, and PM2 is one of the mainstream app servers in the Node.js ecosystem.

Install

Although PM2 is also a Node.js suite, as an app server, we regard it as a similar role to a web server, and it is usually installed globally instead of within a project. The installation command:

 $ npm install pm2 -g

After installation, execute to see if it is successful:

 $ pm2

Initial execution should output the following message:

 __/\\\\\\\\\\\\\____/\\\\____________/\\\\____/\\\\\\\\\_____ _\/\\\/////////\\\_\/\\\\\\________/\\\\\\__/\\\///////\\\___ _\/\\\_______\/\\\_\/\\\//\\\____/\\\//\\\_\///______\//\\\__ _\/\\\\\\\\\\\\\/__\/\\\\///\\\/\\\/_\/\\\___________/\\\/___ _\/\\\/////////____\/\\\__\///\\\/___\/\\\________/\\\//_____ _\/\\\_____________\/\\\____\///_____\/\\\_____/\\\//________ _\/\\\_____________\/\\\_____________\/\\\___/\\\/___________ _\/\\\_____________\/\\\_____________\/\\\__/\\\\\\\\\\\\\\\_ _\///______________\///______________\///__\///////////////__  
 Runtime Edition  
 PM2 is a Production Process Manager for Node.js applications with a built-in Load Balancer.  
 Start and Daemonize any application: $ pm2 start app.js  
 Load Balance 4 instances of api.js: $ pm2 start api.js -i 4  
 Monitor in production: $ pm2 monitor  
 Make pm2 auto-boot at server restart: $ pm2 startup  
 To go further checkout: http://pm2.io/  
 -------------  
usage: pm2 [options] <command>  
pm2 -h, --help all available commands and options pm2 examples display pm2 usage examples pm2 <command> -h help on a specific command  
Access pm2 files in ~/.pm2

The brief introduction above has almost finished the basic usage of PM2, and this article is over.


Of course, things are not that simple. Notice the last sentence of the above message “Access pm2 files in ~/.pm2”, let’s see what is in it first.

~/.pm2/ looks like this:

 .pm2/ ├── logs/ ├── module_conf.json ├── modules/ ├── pids/ └── touch

At present, most of them are empty, and the only thing to pay attention to is logs/. Remember to come here to find records when you want to troubleshoot problems in the future.

The output above shows some usage of PM2 CLI, but in the production environment, we would like to write the configuration into a file. After all, the CLI parameters will always be forgotten, and it is safer to operate in the form of a configuration file, which can also be included in version control management.

Execute the following command in the project root directory to generate the basic configuration file:

 $ cd ~ ./Porjects/liveboard/ $ pm2 init

The output file name is ecosystem.config.js, as follows:

 module.exports = { apps: [ { script: ' index.js ', watch: ' . ' }, { script: ' ./service-worker/ ', watch: [' ./service-worker '] }, ],  
 deploy: { production: { user: ' SSH_USERNAME ', host: ' SSH_HOSTMACHINE ', ref: ' origin/master ', repo: ' GIT_REPOSITORY ', path: ' DESTINATION_PATH ', ' pre-deploy-local ': '', ' post-deploy ': ' npm install && pm2 reload ecosystem.config.js --env production ', ' pre-setup ': '' } } }

The content is quite simple, and most of them can be read as the name implies. apps block defines two Node.js apps, and the deploy block contains some parameters and commands for remote deployment.

In terms of apps block, all configuration items can refer to the PM2 file 〈 Configuration File 〉, which will not be repeated here. The following are my commonly used configurations:

 apps: [ {      // General name: ' liveboard ', script: ' ./build/index.js ', port: 4000 ,  
      // Advanced features instances: 2 , env: { NODE_ENV: " development " }, env_production: { NODE_ENV: " production " }, env_staging: { NODE_ENV: " staging " }, env_development: { NODE_ENV: " development " },  
      // Log files time: true , }, ]

name and port in it are literal meanings. instance below is naturally the number of programs to be opened by this liveboard app. Multiple programs are used to increase the capacity of the service. Here, PM2 will use the cluster mode of Node.js to manage program, the external port 4000 is shared by all liveboard instances, and there will be no problem of grabbing ports.

Further down are several groups of configurations starting with env . env_xxx here can be freely formulated. Of course, there are environment variables in it, and env without any suffix is ​​the default environment variable.

Finally, there is a time: true , which just adds a time stamp to the log.

After configuring it, you can run it:

 $ pm2 start ecosystem.config.js

View managed app status:

 $ pm2 list

The output is as follows:

 ⇆ PM2+ activated ┌────┬───────────┬───────────┬─────────┬─────────┬───────┬────────┬───┬────────┬─────┬────────┬──────┬──────────┐ │ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │ ├────┼───────────┼───────────┼─────────┼─────────┼───────┼────────┼───┼────────┼─────┼────────┼──────┼──────────┤ │ 0 │ liveboard │ default │ 0.0.1 │ cluster │ 11784 │ 63m │ 0 │ online │ 0% │ 32.9mb │ user │ disabled │ │ 1 │ liveboard │ default │ 0.0.1 │ cluster │ 16076 │ 63m │ 0 │ online │ 0% │ 32.0mb │ user │ disabled │ └────┴───────────┴───────────┴─────────┴─────────┴───────┴────────┴───┴────────┴─────┴────────┴──────┴──────────┘

There are also some commonly used commands:

  • $ pm2 restart app_name : Restart the app.
  • $ pm2 stop app_name : Stop app.
  • $ pm2 delete app_name : Terminate app.
  • $ pm2 logs app_name : Display app log messages.

In addition, PM2 can also generate systemd service configuration files, which can be executed as ordinary users:

 $ pm2 startup

it will output:

 [PM2] Init System found: systemd [PM2] To setup the Startup Script, copy/paste the following command: sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u mes --hp /home/mes

Execute as instructed:

 $ sudo env PATH=$ PATH :/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u mes --hp /home/mes

The output message is as follows:

 [PM2] Init System found: systemd Platform systemd Template  
[Unit] Description =PM2 process manager Documentation = https://pm2.keymetrics.io / After =network.target  
[Service] Type =forking User =mes LimitNOFILE =infinity LimitNPROC =infinity LimitCORE =infinity Environment =PATH=/home/mes_staging/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin Environment =PM2_HOME=/home/mes/.pm2 PIDFile =/home/mes/.pm2/pm2.pid Restart =on-failure  
ExecStart =/usr/lib/node_modules/pm2/bin/pm2 resurrect ExecReload =/usr/lib/node_modules/pm2/bin/pm2 reload all ExecStop =/usr/lib/node_modules/pm2/bin/pm2 kill  
[Install] WantedBy =multi-user.target  
Target path /etc/systemd/system/pm2-mes.service  
Command list [ 'systemctl enable pm2-mes' ]  
[PM2] Writing init configuration in /etc/systemd/system/pm2-mes.service [PM2] Making script booting at startup... [PM2] [-] Executing: systemctl enable pm2-mes... Created symlink /etc/systemd/system/multi-user.target.wants/pm2-mes.service → /etc/systemd/system/pm2-mes.service. [PM2] [v] Command successfully executed. +---------------------------------------+ [PM2] Freeze a process list on reboot via: $ pm2 save  
[PM2] Remove init script via: $ pm2 unstartup systemd

As indicated in the message, it helped us generate a systemd service configuration file, and also enabled us, so that after restarting, the PM2 service will automatically run.

The next thing we need to do is to tell PM2 which apps it wants to invoke. Continuing the previous example, first make sure that the app to be run is running:

 $ pm2 start ecosystem.config.cjs $ pm2 list

The output is as follows:

 ⇆ PM2+ activated ┌────┬───────────┬───────────┬─────────┬─────────┬───────┬────────┬───┬────────┬─────┬────────┬──────┬──────────┐ │ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │ ├────┼───────────┼───────────┼─────────┼─────────┼───────┼────────┼───┼────────┼─────┼────────┼──────┼──────────┤ │ 0 │ liveboard │ default │ 0.0.1 │ cluster │ 11784 │ 63m │ 0 │ online │ 0% │ 32.9mb │ user │ disabled │ │ 1 │ liveboard │ default │ 0.0.1 │ cluster │ 16076 │ 63m │ 0 │ online │ 0% │ 32.0mb │ user │ disabled │ └────┴───────────┴───────────┴─────────┴─────────┴───────┴────────┴───┴────────┴─────┴────────┴──────┴──────────┘

Save the currently running app as the app to be brought up when the PM2 service starts:

 $ pm2 save

The output is as follows:

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

This dmp.pm2 is a JSON file, which records a lot of parameters of the previous two app instances.

Finally, of course, it is a wave of rebooting to confirm whether the service is running as usual.

Finally, because the role of PM2 is the app server, a web server responsible for reverse proxy is usually placed before the app server in the formal environment, the most typical one is NGINX, which is responsible for providing external services, and then forwards some requests to the corresponding For the app server of NGINX and PM2, you can refer to < Production Setup with Nginx > of PM2, and if it is Caddy , you can refer to the following caddyfile configuration:

 http:// { handle_path /* { reverse_proxy :4000 } }

The above configuration will forward all requests to port 4000, which is the port that PM2 manages to monitor. As for the HTTP headers to be carried when forwarding, such as X-Forwarded-For and X-Real-IP , Caddy originally Will bring, no additional configuration, GJ.

This article is transferred from: https://editor.leonh.space/2023/pm2/
This site is only for collection, and the copyright belongs to the original author.