使用pm2部署nuxt3项目,操作步骤如下:
①安装
npm install -g pm2 (可能需要 sudo)
pm2 -v 查看安装结果
②pm2使用方式
pm2 主要有 2 种方式:命令行和配置文件
本项目采用配置文件的方式运行(在项目的更目录下运行):
www@HPDEV-31:~/code/project/frontend$ pm2 ecosystem
File /home/www/code/project/frontend/ecosystem.config.js generated
//ecosystem.config.js,下面这个是一个标准格式
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': ''
}
}
};
//ecosystem.config.js,编辑为项目需要的格式
//这个默认的 exec_mode: 'fork'
module.exports = {
apps : [{
name: 'project',
script: './.output/server/index.mjs',
watch: '.' //监听目录用于当指定监听目录文件发生变化时,pm2 将会自动重启应用。实际表现为:当项目发生更改,比如 vue 页面变化了,修改完以后 执行yarn run build,会生成新的.output/server/index.mjs 文件,那么这个就会被watch ,然后自动更新,并且生效。但是在实际使用中,我发现,pm2 自动重启应用以后,页面访问总是会出问题,主要表现在js报错上(可以通过pm2 logs查看)。不得已 手动重启一下才不会有问题。
}]
};
//改为 exec_mode: 'cluster'
module.exports = {
apps : [{
name: 'project',
exec_mode: 'cluster', //修改exec_mode 为 cluster,默认为 fork模式,只有 node 项目才支持cluster模式,官网介绍:https://pm2.keymetrics.io/docs/usage/cluster-mode/
instances: 'max', //配置cluster模式下实例的个数,这里配置为 max 即为 cpu总核数,我查看了我的电脑:12th Gen Intel® Core™ i7-1260P × 16 (12核16线程) ,那么就会启动 16 个实例,实验证明也是这样的结果
script: './.output/server/index.mjs',
watch: '.' //监听目录用于当指定监听目录文件发生变化时,pm2 将会自动重启应用,事实上仍然有问题,见上面分析
}]
};
//上面的watch 问题,我加了 ignore_watch 之后就正常了,好奇怪
module.exports = {
apps : [{
name: 'project',
script: './.output/server/index.mjs',
watch: '.',
ignore_watch : [ // 从监控目录中排除
"node_modules"
],
}]
};
③运行文件
www@HPDEV-31:~/code/project/frontend$ pm2 start ecosystem.config.js
[PM2][WARN] Applications project not running, starting...
[PM2] App [project] launched (1 instances)
┌────┬────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0 │ project │ default │ 0.0.0 │ fork │ 41744 │ 0s │ 0 │ online │ 0% │ 46.9mb │ www │ enabled │
└────┴────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
④配置nginx反向代理
// /etc/nginx/sites-available/test.conf
server {
listen 80;
listen [::]:80;
root /home/www/code/project/public; #网站根目录,既index.php入口文件所在目录,结尾不加 /
index index.php index.html;
server_name project.web.test; # 域名或者ip地址
location ~ /img/user_image/(.*) {
alias /var/www/dms/profiles/$1;
}
location ~ /(login|logout|admin|api|sso|build|upload|statics|(user/register)|(verify/email)|(user/profile-image)|_wdt|_profiler|otp){
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ { # 支持php, 下面的配置是默认的,我只是删掉了没用的,并接触了注释。
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock; # 这里对应着上面安装的php7.0
}
location / {
proxy_pass http://localhost:3000; #这个3000端口就是nuxt3项目运行的默认端口
}
}
⑤查看应用列表:pm2 list / pm2 status / pm2 ls
www@HPDEV-31:~/code/project/frontend$ pm2 list
┌────┬────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0 │ project │ default │ 0.0.0 │ fork │ 41744 │ 32m │ 0 │ online │ 0% │ 79.3mb │ www │ enabled │
└────┴────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
⑥查看指定应用信息:pm2 describe [id number]
www@HPDEV-31:~/code/project/frontend$ pm2 describe 0
Describing process with id 0 - name project
┌───────────────────┬───────────────────────────────────────────────────────────┐
│ status │ online │
│ name │ project │
│ namespace │ default │
│ version │ 0.0.0 │
│ restarts │ 0 │
│ uptime │ 36m │
│ script path │ /home/www/code/project/frontend/.output/server/index.mjs │
│ script args │ N/A │
│ error log path │ /home/www/.pm2/logs/project-error.log │
│ out log path │ /home/www/.pm2/logs/project-out.log │
│ pid path │ /home/www/.pm2/pids/project-0.pid │
│ interpreter │ node │
│ interpreter args │ N/A │
│ script id │ 0 │
│ exec cwd │ /home/www/code/project/frontend │
│ exec mode │ fork_mode │
│ node.js version │ 19.3.0 │
│ node env │ N/A │
│ watch & reload │ ✔ │
│ unstable restarts │ 0 │
│ created at │ 2023-03-22T07:02:19.692Z │
└───────────────────┴───────────────────────────────────────────────────────────┘
Revision control metadata
┌──────────────────┬────────────────────────────────────────────────┐
│ revision control │ git │
│ remote url │ ssh://git@gitlab.www.com:9922/dev/project.git │
│ repository root │ /home/www/code/project │
│ last update │ 2023-03-22T07:02:19.748Z │
│ revision │ 15b8f2de003ad56a977a261016ea13a7159e3db9 │
│ comment │ home page │
│ branch │ guoshipeng │
└──────────────────┴────────────────────────────────────────────────┘
Actions available
┌────────────────────────┐
│ km:heapdump │
│ km:cpu:profiling:start │
│ km:cpu:profiling:stop │
│ km:heap:sampling:start │
│ km:heap:sampling:stop │
└────────────────────────┘
Trigger via: pm2 trigger project <action_name>
Code metrics value
┌────────────────────────┬──────────────────────┐
│ Used Heap Size │ 21.52 MiB │
│ Heap Usage │ 93.26 % │
│ Heap Size │ 23.08 MiB │
│ Event Loop Latency p95 │ 1.19 ms │
│ Event Loop Latency │ 0.43 ms │
│ Active handles │ 4 │
│ Active requests │ 0 │
│ HTTP │ 0 req/min │
│ HTTP P95 Latency │ 16.54999999999999 ms │
│ HTTP Mean Latency │ 0 ms │
└────────────────────────┴──────────────────────┘
Divergent env variables from local env
Add your own code metrics: http://bit.ly/code-metrics
Use `pm2 logs project [--lines 1000]` to display logs
Use `pm2 env 0` to display environment variables
Use `pm2 monit` to monitor CPU and Memory usage project
⑦其它命令:pm2 logs / pm2 monit / pm2 plus(跳转到在线检测平台:https://id.keymetrics.io)
⑧停止应用:pm2 stop [id number / name / all]
www@HPDEV-31:~/code/project/frontend$ pm2 stop 0
[PM2] Applying action stopProcessId on app [0](ids: [ '0' ])
[PM2] [project](0) ✓
┌────┬────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0 │ project │ default │ 0.0.0 │ fork │ 0 │ 0 │ 0 │ stopped │ 0% │ 0b │ www │ disabled │
└────┴────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
⑨重启应用:pm2 reload [id number / name / all]
www@HPDEV-31:~/code/project/frontend$ pm2 reload 0
Use --update-env to update environment variables
[PM2] Applying action reloadProcessId on app [0](ids: [ '0' ])
[PM2] [project](0) ✓
www@HPDEV-31:~/code/project/frontend$ pm2 reload project
Use --update-env to update environment variables
[PM2] Applying action reloadProcessId on app [project](ids: [ 0 ])
[PM2] [project](0) ✓
www@HPDEV-31:~/code/project/frontend$ pm2 reload all
Use --update-env to update environment variables
[PM2] Applying action reloadProcessId on app [all](ids: [ 0 ])
[PM2] [project](0) ✓
⑩删除应用:pm2 delete [id number / name / all]
删除应用几乎不会造成任何后果,只是在管理列表中删除了这一项,并不会删除项目文件
⑪通过pm2支持的npm启动方式启动项目:
www@HPDEV-31:~/code/project/frontend$ pm2 start npm --name project -- run start --watch
[PM2] Starting /usr/local/bin/npm in fork_mode (1 instance)
[PM2] Done.
┌────┬────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├────┼────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 0 │ project │ default │ N/A │ fork │ 0 │ 0 │ 15 │ errored │ 0% │ 0b │ www │ enabled │
│ 1 │ project │ default │ N/A │ fork │ 11949 │ 0s │ 0 │ online │ 0% │ 31.4mb │ www │ enabled │
└────┴────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
id 为0的那个是通过 pm2 start yarn --name project -- run start --watch, 证明通过pm2 通过yarn 启动是有问题的,报:
0|project | /usr/share/yarn/bin/yarn:2
0|project | argv0=$(echo "$0" | sed -e 's,\\,/,g')
0|project | ^^^^
0|project |
0|project | SyntaxError: missing ) after argument list
id 为1的那个是通过npm 启动的,没任何问题
但是这种方式,watch 还是会出问题,还是觉得通过配置文件启动比较靠谱
⑫通过最普通的 nohup 执行命令,这种现在过时了
www@HPDEV-31:~/code/project/frontend$ nohup node .output/server/index.mjs & //默认会在当前路径下生成nohup.out文件
[2] 17471
www@HPDEV-31:~/code/project/frontend$ nohup: ignoring input and appending output to 'nohup.out'
^C
www@HPDEV-31:~/code/project/frontend$ netstat -anlp | grep 17471
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp6 0 0 :::3000 :::* LISTEN 17471/node
www@HPDEV-31:~/code/project/frontend$ kill 17471
www@HPDEV-31:~/code/project/frontend$
[2]- Terminated nohup node .output/server/index.mjs
⑬本地启动pm2-web服务
sudo npm install -g pm2-web
当前项目下执行:pm2-web
