Introduction
What’s pm2?
- pm2 is a process manager of Node.js
What does pm2 solve?
- pm2 can re-launch Node service after it crashes.
- pm2 can re-launch Node service after the server reboot
- pm2 can run multiple processes with multiple cores of CPU to achieve Load Balancer like effect.
- It features kind of rolling update, 0 downtime upgrade with Graceful Reload
- Multiple services with multiple processes, significantly boost the performance.
- Schedule to restart periodically
- pm2 provides much information, including restart number, CPU usage, memory usage, process id, etc.
- pm2 allows auto-restart under specific condition, such as ‘up-time’, ‘memory usage’, etc.
- pm2 can organise log, periodically split the log and keep the number we specify, delete exceeded ones.
- pm2 provides simple deployment method, and support multiple server deployment
- pm2 can integrate with CI / CD tool, as well as CI / CD deployment
What are you waiting for?
Here are the coverage of this article:
- Installation
- pm2 with CLI
- pm2 with ecosystem
- pm2 with ecosystem on deployment
- pm2 deployment with GitLab CI / CD Runner
installation
- Global installation
npm install pm2@latest -g
pm2 with CLI
Launch node project with pm2 with CLI, see the example below:
pm2 start location/fileName.js --name appName \ |
As to the meaning of CLI mentioned above, refer to the followings
The flag
--name
Specify an app name--watch
Watch and Restart app when files change--max-memory-restart
Set memory threshold for app reload--log
Specify log file--output
specify out log file--error
specify error log file--log-date-format
prefix logs with custom formated timestamp--merge-logs
when running mutiple process with same app name, do not split file by id--arg1
--arg2
--arg3
Pass extra arguments to the script--restart-delay
Delay between automatic restarts--time
Prefix logs with time--no-autorestart
Do not auto restart app--cron
Specify cron for forced restart--no-daemon
Attach to application log
cluster mode
- pm2 automatically detect the number of CPU, launching as many processes as possible. The above mentioned flags could be attached on cluster mode. Specify how many process you would like after
-i
. pm2 would automatically detect max number if you put0
ormax
pm2 start app.js -i max
Process management
Kill the process directly and restart a new process
pm2 restart app_name
If it’s cluster mode,
reload
would reload process one by one and always keep one alive to achieve 0 downtime upgradepm2 reload app_name
Stop the app
pm2 stop app_name
Stop and delete the app
pm2 delete app_name
except for specifying app_name, you could also:
all
: all the Appsid
: the id of the process
Show the status of management
pm2 [list|ls|status] |
Logs
specify filepath to output both out and error logs
pm2 logs
Display X lines of api log file
pm2 logs --lines 200
Show logs at specified App id
pm2 logs id
Formatted output
pm2 logs --format
Output logs in json format
pm2 logs --json
Empty all log files
pm2 flush
Cancel logs
By specifying log path todev/null
, you could cancel log
Rotated Log
If you’ve ever seen a single extremely big file with years of log, or you’ve ever found thousands of log files in a log folder, or you’ve ever come across weird log file naming, or you found a considerably huge amount consumed after you type du -sh
in a folder, congratulations! Here is the solution.
Installation
pm2 install pm2-logrotate |
Find the config file at /home/user/.pm2/module_conf.json
Parameters
- max_size (Defaults to 10M):
When a file size becomes higher than this value it will rotate it (its possible that the worker check the file after it actually pass the limit) . You can specify the unit at then end: 10G, 10M, 10K - retain (Defaults to 30 file logs):
This number is the number of rotated logs that are keep at any one time, it means that if you have retain = 7 you will have at most 7 rotated logs and your current one. - compress (Defaults to false):
Enable compression via gzip for all rotated logs - dateFormat (Defaults to YYYY-MM-DD_HH-mm-ss) :
Format of the data used the name the file of log - rotateModule (Defaults to true) :
Rotate the log of pm2’s module like other apps - workerInterval (Defaults to 30 in secs) :
You can control at which interval the worker is checking the log’s size (minimum is 1) - rotateInterval (Defaults to 0 0 * * * everyday at midnight):
This cron is used to a force rotate when executed. We are using node-schedule to schedule cron, so all valid cron for node-schedule is valid cron for this option. Cron style : - TZ (Defaults to system time):
This is the standard tz database timezone used to offset the log file saved. For instance, a value of Etc/GMT-1, with an hourly log, will save a file at hour 14 GMT with hour 13 GMT-1 in the log name.
Graph
* * * * * * |
Terminal Based Dashboard
pm2 monit |
pm2 ecosystem
CLI tool is good though, typo is so difficult to be eliminated. We could easily solve this problem by carefully crafting our ecosystem file. Except that some configs are meant to be changed in the future, we could eliminate typo issue. Besides, ecosystem cloud be controlled by Version Control System, like Git.
Generate ecosystem file
pm2 ecosystem |
CLI
Same as above mentioned.
pm2 start ecosystem.config.js |
Start specific App via ecosystem file
We could start specific App that we’d crafted in the ecosystem.config.js file.
pm2 start ecosystem.config.js --only yourApp |
Parameter injection
Take a look on the following example. If I key in pm2 start ecosystem --only app1 --env production
, then pm2 wil use the environment within env_production object.
Parameter example
You could find tons of parameters below. Surely we are not going to use all of them, you could take a look on each of them and only leave those you need.
module.exports = { |
pm2 Deployment
pm2 Deployment supports multiple server deployment, also, which could integrate with CI / CD tool, automatically deploy after submitting a commit.
Prerequisite
- Firstly, have you prepared the ssh key for local to remote?
The connection between local and remote is required.
Simply speaking, you need to put a private key locally, and put public key remotely. You could Google how to set up ssh key. - Secondly, since pm2 will ssh to remote server, and then clone our project from either GitHub or Gitlab. So make sure that
cloning from Git Repository to remote server is feasible.
You will need to put a private key on your remote server, and the public key on Git Repository. Please also Google how to set up the key on GitHub or GitLab - Since the first time we connect to remote server, ssh would prompt to ask if it’s okay to put the public key of remote server to local known host, we will need to config it in advance. Otherwise, the deployment would fail. We could cancel the hostKeyChecking feature.
echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
- And then, we need to properly craft ecosystem file, let’s refer to the deploy example above.
- Finally, make sure ssh tunnel is not blocked (default port 22)
Initialise remote folder
Before deploying, we need to set up the project on remote server. We could pass different parameters and pm2 would deploy accordingly.
pm2 deploy ecosystem.config.js production setup |
Deploy
- Deploy
After initially setting up our project on remote server, we could start to deploy.pm2 deploy ecosystem.config.js production
- Here I’ve listed some parameters as follows, and you could also check details by
pm2 deploy help
pm2 deploy <configuration_file> <environment> <command> |
Relative commands of Deployment
pm2 startOrRestart all.json # Invoke restart on all apps in JSON
pm2 startOrReload all.json # Invoke reloadForce deployment
That means that you have changes in your local system that aren’t pushed inside your git repository, and since the deploy script get the update via git pull they will not be on your server. If you want to deploy without pushing any data, you can append the –force option:pm2 deploy ecosystem.json production --force
CI / CD Deployment
- Implement deployment by integrating pm2 with GitLab CI / CD Runner, and here is the gitlab.yml example below:
# Use small-size image |
- If you set it properly, a simple git push would trigger the CI / CD deployment
Auto start after reboot
Generate startup script
pm2 startup
Cancel startup script
pm2 unstartup
Save the current process for next default startup
pm2 save
如果有更新 node 的版本,記得更新 script
If you upgrade your node, udpate your script as well
pm2 unstartup && pm2 startup && pm2 save
Reload after when content changes
Monitor files under the project folder and subfolder, and ignore node_module
cd /path/to/my/app |
update pm2
npm install pm2@latest -g && pm2 update |
pm2 cheat sheet
# Fork mode |
Auto completion
- pm2 command support auto completion
pm2 completion install
疑難雜症
- Encounter
Error: ENOENT: no such file or directory, uv_cwd
- Refer here
參考資料
pm2 官網
pm2 logrotate
- Refer here
Comments