[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"content-using_pm2_deploy":3,"$f1tsjaxx14jayx":23},{"id":4,"type":5,"slug":6,"title":7,"date":8,"category":9,"tags":10,"body_markdown":14,"permalink":15,"excerpt_src":16,"media_type":16,"media_title":16,"media_author":16,"media_url":16,"rating":16,"layout":16,"pv":17,"admin_only":17,"created_at":18,"updated_at":18,"deleted_at":16,"status":19,"html":20,"excerpt":21,"cover":22},163,"article","using_pm2_deploy","使用PM2 Deploy部署基于Git版本管理的网站应用","2014-11-19 13:29","web",[11,12,13],"Node.js","PM2","部署","\n按照官方介绍，PM2是一款用于生产环境Node.js应用进程管理的工具。按照民间介绍，它主要有这样几个功能：保证Node.js应用永远在线（挂掉自动重启）、自动负载均衡、零中断重启应用等。\n\n鉴于它是如此优秀，这里还是简要介绍一下前两个功能。\n\n## 安装\n\n首先，它是一个Node.js写的工具，使用npm即可安装使用：\n\n\tnpm install -g pm2\n\n## 运行Node.js程序\n\n如果不使用pm2，运行Node.js程序是这样：\n\n\tnode xxx.js\n\n使用pm2，是这样：\n\n\tpm2 start xxx.js\n\n### 监视模式\n\n如果你正在开发Node.js应用，需要在代码变更后自动重启应用，只需要在pm2的参数中加上`--watch`即可：\n\n\tpm2 start xxx.js --watch\n\n\u003C!-- more -->\n\n### cluster模式\n\n默认情况下pm2是以fork模式启动应用的，如果以cluster模式启动的话，则可以使用pm2自带的负载均衡、零间断重启等功能。\n\n\tpm2 start xxx.js -i 4\n\n上面的命令会以cluster模式启动4个应用进程，并自动为它们提供负载均衡，并且可以使用gracefulReload达到更新应用时不中断服务的效果。\n\n> 关于cluster模式，可参见朴灵《深入浅出Node.js》一书。\n>\n> pm2低版本默认是以cluster模式启动的。\n\n## 部署应用\n\n这才是本文的重点。PM2的部署功能可以实现网站应用的半自动部署功能。注意本文标题没有加“Node.js”，意味着这个功能并不只适用于Node.js网站应用，事实上它部署功能是用shell写的，跟网站使用什么语言没什么关系。\n\nPM2的部署功能与版本管理工具（Git，不确定是否支持SVN，下文以Git为例）结合比较紧，因此需要保证网站项目使用版本管理工具管理代码，并且服务器可以访问到版本管理服务器。\n\n部署功能是在新版本（0.12？）中才添加进来的。如果你使用的是旧版本的，需要先升级：\n\n```sh\nnpm install -g pm2@latest\npm2 updatePM2\n```\n\n接下来需要建立一个部署的配置文件，这个文件在本机（操作发布的机器）和服务器上都需要有，因此最好放入Git版本管理中，并且推送到远程代码库（Git服务器）。\n\n切换到项目目录下，然后执行\n\n```sh\npm2 ecosystem\n```\n\n即可得到一个示例json文件（例如我得到的是`ecosystem.json5`），将它做对应的修改，大致如下：\n\n```json\n{\n\t\"apps\" : [{\n\t\t\"name\" : \"xxx\", \u002F\u002F项目的名字\n\t\t\"script\" : \"xxx.js\",  \u002F\u002F项目主入口（Node.js）\n\t\t\"env\": {\n\t\t\t\"COMMON_VARIABLE\": \"true\"\n\t\t},\n\t\t\"env_production\" : {\n\t\t\t\"NODE_ENV\": \"production\"\n\t\t}\n\t}],\n\t\"deploy\" : {\n\t\t\"production\" : {\n\t\t\t\"user\" : \"toobug\",\n\t\t\t\"host\" : \"server.toobug.net\",\n\t\t\t\"ref\"  : \"origin\u002Fmaster\", \u002F\u002F需要部署的分支\n\t\t\t\"repo\" : \"git@github.com:TooBug\u002Fxxx.git\",\n\t\t\t\"path\" : \"\u002Fvar\u002Fwww\u002Fxxx\", \u002F\u002Fweb目录\n\t\t\t\"post-deploy\" : \"npm install && pm2 startOrRestart ecosystem.json --env production\"\n\t\t}\n\t}\n}\n```\n\n需要注意：\n\n1. `apps.name`和`apps.script`应该与PM2识别应用有关，后续执行`pm2 restart`的时候可以对应到进程（未证实）\n2. `deploy`中可以含有多个环境，需要能够通过SSH（公钥认证）登录服务器\n3. web目录并不是真正的放版本库文件的目录，PM2会再建立一个`source`子目录，这个才是真正放代码的目录\n4. `post-deploy`是指代码部署完之后执行的命令，这里以Node.js为例子，执行依赖安装，然后重启PM2中的进程\n\n然后就可以使用\n\n```sh\npm2 deploy ecosystem.json production\n```\n\n自动发布网站项目了，非常方便。\n\n```sh\n$>pm2 deploy dev\n--> Deploying to production environment\n--> on host server.toobug.net\n  ○ deploying\n  ○ hook pre-deploy\n  ○ fetching updates\nFetching origin\n  ○ resetting HEAD to origin\u002Fmaster\nHEAD is now at eda2cdd xxx\n  ○ executing post-deploy npm install && pm2 startOrRestart ecosystem.json --env production\nmanpath: can't set the locale; make sure $LC_* and $LANG are correct\nNow using node v0.11.13\n[PM2] restartProcessId process id 0\n┌──────────┬────┬──────┬──────┬────────┬───────────┬────────┬─────────────┬──────────┐\n│ App name │ id │ mode │ PID  │ status │ restarted │ uptime │      memory │ watching │\n├──────────┼────┼──────┼──────┼────────┼───────────┼────────┼─────────────┼──────────┤\n│ xxx      │ 0  │ fork │ 7384 │ online │        33 │ 0s     │ 12.438 MB   │ disabled │\n└──────────┴────┴──────┴──────┴────────┴───────────┴────────┴─────────────┴──────────┘\n Use pm2 info \u003Cid|name> to get more details about an app\n  ○ hook test\n  ○ successfully deployed origin\u002Fmaster\n--> Success\n```\n\n在使用过程中还有几个值得注意的点：\n\n- 在部署过程中，PM2会执行一次`git reset --hard`，意味着如果你修改了配置文件之类的，会被还原，因此最好使用环境变量或者新建文件（不在管理库中）的方式来指定服务器专用的配置项（比如数据库连接信息等）\n- 执行服务器命令时需要关注环境变量，比如使用nvm来管理node版本的话，有可能导致PM2连接后找不到node（以及npm\u002Fpm2）所在路径，解决办法是在脚本最前面加上指定环境变量的脚本，例如`source ~\u002F.bashrc`\n\n## End\n\n就是这样，水文一篇，你要是当成PM2的广告读也行，主要是这个功能真的是很方便。尤其是有多个环境的话，几条命令就能搞定，再也不用登录服务器手工做一堆事情了。\n","\u002Farticle\u002Fusing_pm2_deploy.html",null,0,"2026-08-28 04:37:17","published","\u003Cp>按照官方介绍，PM2是一款用于生产环境Node.js应用进程管理的工具。按照民间介绍，它主要有这样几个功能：保证Node.js应用永远在线（挂掉自动重启）、自动负载均衡、零中断重启应用等。\u003C\u002Fp>\n\u003Cp>鉴于它是如此优秀，这里还是简要介绍一下前两个功能。\u003C\u002Fp>\n\u003Ch2>安装\u003C\u002Fh2>\n\u003Cp>首先，它是一个Node.js写的工具，使用npm即可安装使用：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>npm install -g pm2\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2>运行Node.js程序\u003C\u002Fh2>\n\u003Cp>如果不使用pm2，运行Node.js程序是这样：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>node xxx.js\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>使用pm2，是这样：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>pm2 start xxx.js\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>监视模式\u003C\u002Fh3>\n\u003Cp>如果你正在开发Node.js应用，需要在代码变更后自动重启应用，只需要在pm2的参数中加上\u003Ccode>--watch\u003C\u002Fcode>即可：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>pm2 start xxx.js --watch\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>cluster模式\u003C\u002Fh3>\n\u003Cp>默认情况下pm2是以fork模式启动应用的，如果以cluster模式启动的话，则可以使用pm2自带的负载均衡、零间断重启等功能。\u003C\u002Fp>\n\u003Cpre>\u003Ccode>pm2 start xxx.js -i 4\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>上面的命令会以cluster模式启动4个应用进程，并自动为它们提供负载均衡，并且可以使用gracefulReload达到更新应用时不中断服务的效果。\u003C\u002Fp>\n\u003Cblockquote>\n\u003Cp>关于cluster模式，可参见朴灵《深入浅出Node.js》一书。\u003C\u002Fp>\n\u003Cp>pm2低版本默认是以cluster模式启动的。\u003C\u002Fp>\n\u003C\u002Fblockquote>\n\u003Ch2>部署应用\u003C\u002Fh2>\n\u003Cp>这才是本文的重点。PM2的部署功能可以实现网站应用的半自动部署功能。注意本文标题没有加“Node.js”，意味着这个功能并不只适用于Node.js网站应用，事实上它部署功能是用shell写的，跟网站使用什么语言没什么关系。\u003C\u002Fp>\n\u003Cp>PM2的部署功能与版本管理工具（Git，不确定是否支持SVN，下文以Git为例）结合比较紧，因此需要保证网站项目使用版本管理工具管理代码，并且服务器可以访问到版本管理服务器。\u003C\u002Fp>\n\u003Cp>部署功能是在新版本（0.12？）中才添加进来的。如果你使用的是旧版本的，需要先升级：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>npm install -g pm2@latest\npm2 updatePM2\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>接下来需要建立一个部署的配置文件，这个文件在本机（操作发布的机器）和服务器上都需要有，因此最好放入Git版本管理中，并且推送到远程代码库（Git服务器）。\u003C\u002Fp>\n\u003Cp>切换到项目目录下，然后执行\u003C\u002Fp>\n\u003Cpre>\u003Ccode>pm2 ecosystem\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>即可得到一个示例json文件（例如我得到的是\u003Ccode>ecosystem.json5\u003C\u002Fcode>），将它做对应的修改，大致如下：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>{\n\t&quot;apps&quot; : [{\n\t\t&quot;name&quot; : &quot;xxx&quot;, \u002F\u002F项目的名字\n\t\t&quot;script&quot; : &quot;xxx.js&quot;,  \u002F\u002F项目主入口（Node.js）\n\t\t&quot;env&quot;: {\n\t\t\t&quot;COMMON_VARIABLE&quot;: &quot;true&quot;\n\t\t},\n\t\t&quot;env_production&quot; : {\n\t\t\t&quot;NODE_ENV&quot;: &quot;production&quot;\n\t\t}\n\t}],\n\t&quot;deploy&quot; : {\n\t\t&quot;production&quot; : {\n\t\t\t&quot;user&quot; : &quot;toobug&quot;,\n\t\t\t&quot;host&quot; : &quot;server.toobug.net&quot;,\n\t\t\t&quot;ref&quot;  : &quot;origin\u002Fmaster&quot;, \u002F\u002F需要部署的分支\n\t\t\t&quot;repo&quot; : &quot;git@github.com:TooBug\u002Fxxx.git&quot;,\n\t\t\t&quot;path&quot; : &quot;\u002Fvar\u002Fwww\u002Fxxx&quot;, \u002F\u002Fweb目录\n\t\t\t&quot;post-deploy&quot; : &quot;npm install &amp;&amp; pm2 startOrRestart ecosystem.json --env production&quot;\n\t\t}\n\t}\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>需要注意：\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Ccode>apps.name\u003C\u002Fcode>和\u003Ccode>apps.script\u003C\u002Fcode>应该与PM2识别应用有关，后续执行\u003Ccode>pm2 restart\u003C\u002Fcode>的时候可以对应到进程（未证实）\u003C\u002Fli>\n\u003Cli>\u003Ccode>deploy\u003C\u002Fcode>中可以含有多个环境，需要能够通过SSH（公钥认证）登录服务器\u003C\u002Fli>\n\u003Cli>web目录并不是真正的放版本库文件的目录，PM2会再建立一个\u003Ccode>source\u003C\u002Fcode>子目录，这个才是真正放代码的目录\u003C\u002Fli>\n\u003Cli>\u003Ccode>post-deploy\u003C\u002Fcode>是指代码部署完之后执行的命令，这里以Node.js为例子，执行依赖安装，然后重启PM2中的进程\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>然后就可以使用\u003C\u002Fp>\n\u003Cpre>\u003Ccode>pm2 deploy ecosystem.json production\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>自动发布网站项目了，非常方便。\u003C\u002Fp>\n\u003Cpre>\u003Ccode>$&gt;pm2 deploy dev\n--&gt; Deploying to production environment\n--&gt; on host server.toobug.net\n  ○ deploying\n  ○ hook pre-deploy\n  ○ fetching updates\nFetching origin\n  ○ resetting HEAD to origin\u002Fmaster\nHEAD is now at eda2cdd xxx\n  ○ executing post-deploy npm install &amp;&amp; pm2 startOrRestart ecosystem.json --env production\nmanpath: can't set the locale; make sure $LC_* and $LANG are correct\nNow using node v0.11.13\n[PM2] restartProcessId process id 0\n┌──────────┬────┬──────┬──────┬────────┬───────────┬────────┬─────────────┬──────────┐\n│ App name │ id │ mode │ PID  │ status │ restarted │ uptime │      memory │ watching │\n├──────────┼────┼──────┼──────┼────────┼───────────┼────────┼─────────────┼──────────┤\n│ xxx      │ 0  │ fork │ 7384 │ online │        33 │ 0s     │ 12.438 MB   │ disabled │\n└──────────┴────┴──────┴──────┴────────┴───────────┴────────┴─────────────┴──────────┘\n Use pm2 info &lt;id|name&gt; to get more details about an app\n  ○ hook test\n  ○ successfully deployed origin\u002Fmaster\n--&gt; Success\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>在使用过程中还有几个值得注意的点：\u003C\u002Fp>\n\u003Cul>\n\u003Cli>在部署过程中，PM2会执行一次\u003Ccode>git reset --hard\u003C\u002Fcode>，意味着如果你修改了配置文件之类的，会被还原，因此最好使用环境变量或者新建文件（不在管理库中）的方式来指定服务器专用的配置项（比如数据库连接信息等）\u003C\u002Fli>\n\u003Cli>执行服务器命令时需要关注环境变量，比如使用nvm来管理node版本的话，有可能导致PM2连接后找不到node（以及npm\u002Fpm2）所在路径，解决办法是在脚本最前面加上指定环境变量的脚本，例如\u003Ccode>source ~\u002F.bashrc\u003C\u002Fcode>\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2>End\u003C\u002Fh2>\n\u003Cp>就是这样，水文一篇，你要是当成PM2的广告读也行，主要是这个功能真的是很方便。尤其是有多个环境的话，几条命令就能搞定，再也不用登录服务器手工做一堆事情了。\u003C\u002Fp>\n","\u003Cp>按照官方介绍，PM2是一款用于生产环境Node.js应用进程管理的工具。按照民间介绍，它主要有这样几个功能：保证Node.js应用永远在线（挂掉自动重启）、自动负载均衡、零中断重启应用等。\u003C\u002Fp>\n\u003Cp>鉴于它是如此优秀，这里还是简要介绍一下前两个功能。\u003C\u002Fp>\n\u003Ch2>安装\u003C\u002Fh2>\n\u003Cp>首先，它是一个Node.js写的工具，使用npm即可安装使用：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>npm install -g pm2\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2>运行Node.js程序\u003C\u002Fh2>\n\u003Cp>如果不使用pm2，运行Node.js程序是这样：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>node xxx.js\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>使用pm2，是这样：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>pm2 start xxx.js\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>监视模式\u003C\u002Fh3>\n\u003Cp>如果你正在开发Node.js应用，需要在代码变更后自动重启应用，只需要在pm2的参数中加上\u003Ccode>--watch\u003C\u002Fcode>即可：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>pm2 start xxx.js --watch\n\u003C\u002Fcode>\u003C\u002Fpre>\n","",{"total":24,"totalRoots":24,"comments":25,"pv":17},1,[26],{"id":27,"content":28,"user_id":29,"nick":30,"link":22,"date":31,"rid":17,"vote_up":17,"vote_down":17,"visible":32},128,"\u003Cp>好文\u003C\u002Fp>",64,"junhey","2016-03-03 06:59:32",true]