记录运用Webhook实现项目自动部署的过程。
背景
“曾小满的盒子”第二版,采用了MVC三层架构,前端使用了PHP Laravel框架的blade作为模版渲染引擎。
在第三版中,网站采用了前后端分离的架构,后端仍然由PHP Laravel提供服务,前端考虑到SEO优化的问题选用了Nuxt.js(Vue SSR)作为界面框架。
之前使用PHP的模版引擎编写页面,只需替换服务器端有变动更新文件,php-fpm热重载后就能看到最新的页面内容。
而在前后端分离这种模式下部署项目就需要多一些步骤,多操作几次就发现这些步骤比较机械化,我们可以借助Webhook来进行项目自动部署。
部署分析
使用前端界面框架做UI开发,进行项目部署时,需要经历如下几个步骤:
- Pull Commit - 拉取变动(从Git或Svn拉取最新的commit)
- Stop Project - 停止(项目离线)
- Install Denpendecies - 安装依赖(项目依赖如果有变动的话)
- Build Project - 编译构建
- Run Project - 运行项目(项目上线)
上面几个步骤是针对小型项目(如我的个人网站)所写,实际情况中技术栈不同步骤会有所差异。 同时,在工作环境中,一般会有专门的编译服务器承担编译构建的工作。
开发变动完成的最后一步通常是推送代码到Git/Svn,而部署的第一步是拉取Git/Svn中的变动。
Webhook就是介于这两个操作之间的一个“挂钩”,开发者提交完变动后,服务器便在“挂钩”的影响下自动开始部署流程。
(来源于维基百科,关于Webhook的简介)在web开发过程中的webhook,是一种通过通常的callback,去增加或者改变web page或者web app行为的方法。这些callback可以由第三方用户和开发者维持当前,修改,管理,而这些使用者与网站或者应用的原始开发没有关联。webhook这个词是由Jeff Lindsay在2007年在计算机科学hook项目第一次提出的。
Webhook是一个概念,具体实现主要是通过对一个URL进行监听,具体怎么监听就可谓“八仙过海各显神通”了,监听到了变动后执行部署脚本进行项目部署。
变化的通知主要通过Githook来进行,项目进行Notify URL配置,以后每收到一次git push,git服务器就会去主动请求留下的Githook地址以达到通知的目的。
(上面这一部分本文不做探究)
对于我们而言,需要做的便是编写部署流程中的执行脚本,并进行测试,保证自动部署流程平滑进行。
部署脚本
部署脚本可以选择不同的编程语言调用系统API来编写,这里我选用Shell来编写。
关键步骤如下:
进入项目目录
cd $PROJECT_PATH
echo "Into path $PWD"
停止运行中的项目
sudo pm2 stop $PROJECT_NAME
拉取项目代码变动
sudo git reset --hard origin/master
sudo git pull
sudo chown -R www:www $PROJECT_PATH
安装依赖
yarn
# or npm insatll
运行项目
为了保证项目能够持久驻守系统,我选用了node项目管理器pm2来做项目运行支持。
不同情况下可以选择不同的工具。
sudo pm2 start $PROJECT_NAME
运行日志
将上面步骤的代码进行控制台输出优化后就会变得人性化而易用,以下是我的项目部署后每次输出的日志:
Deploy ShareManBoxNuxt
=================================
Start time : 2019-10-06 00:34:18
=================================
[Centos] Enter work directory
Into path /www/wwwroot/ShareManNuxt
=================================
[Pm2] Stop running project
[PM2] Applying action stopProcessId on app [shareman-box-v3](ids: 0)
[PM2] [shareman-box-v3](0) ✓
┌─────────────────┬────┬─────────┬──────┬─────┬─────────┬─────────┬────────┬─────┬────────┬──────┬──────────┐
│ App name │ id │ version │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │
├─────────────────┼────┼─────────┼──────┼─────┼─────────┼─────────┼────────┼─────┼────────┼──────┼──────────┤
│ shareman-box-v3 │ 0 │ 0.33.4 │ fork │ 0 │ stopped │ 0 │ 0 │ 0% │ 0 B │ root │ disabled │
└─────────────────┴────┴─────────┴──────┴─────┴─────────┴─────────┴────────┴─────┴────────┴──────┴──────────┘
Use `pm2 show ` to get more details about an app
=================================
[Git] Pull new commit
HEAD is now at f0e37f1 feat: update day item style
Updating f0e37f1..9c72ee8
Fast-forward
components/Pagination.vue | 2 +-
components/Waterfall.vue | 4 +-
components/item/blog.vue | 6 +-
components/item/common.vue | 6 +-
components/item/day-backup.vue | 4 +-
components/item/day.vue | 18 +--
components/item/idea.vue | 4 +-
components/item/mailbox.vue | 6 +-
components/item/movie.vue | 6 +-
components/item/plan.vue | 8 +-
components/item/project.vue | 4 +-
pages/day/_date.vue | 342 ++++++++++++++++++++++++++---------------
plugins/helper.js | 14 +-
13 files changed, 255 insertions(+), 169 deletions(-)
=================================
[Yarn] Install dependencies
yarn install v1.12.3
[1/4] Resolving packages...
success Already up-to-date.
Done in 0.80s.
=================================
[Yarn] Build project
yarn run v1.12.3
$ nuxt build
ℹ Production build
✔ Builder initialized
✔ Nuxt files generated
ℹ Compiling Client
✔ Client: Compiled successfully in 39.28s
ℹ Compiling Server
✔ Server: Compiled successfully in 5.96s
Done in 67.09s.
=================================
[Pm2] Start project
[PM2] Applying action restartProcessId on app [shareman-box-v3](ids: 0)
[PM2] [shareman-box-v3](0) ✓
[PM2] Process successfully started
┌─────────────────┬────┬─────────┬──────┬───────┬────────┬─────────┬────────┬─────┬───────────┬──────┬──────────┐
│ App name │ id │ version │ mode │ pid │ status │ restart │ uptime │ cpu │ mem │ user │ watching │
├─────────────────┼────┼─────────┼──────┼───────┼────────┼─────────┼────────┼─────┼───────────┼──────┼──────────┤
│ shareman-box-v3 │ 0 │ 0.33.4 │ fork │ 31713 │ online │ 0 │ 0s │ 0% │ 13.8 MB │ root │ disabled │
└─────────────────┴────┴─────────┴──────┴───────┴────────┴─────────┴────────┴─────┴───────────┴──────┴──────────┘
Use `pm2 show ` to get more details about an app
=================================
[Webhook] Deploy completely
=================================
End time : 2019-10-06 00:35:56