记录运用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地址以达到通知的目的。

WebHook实现前端项目自动部署(Nuxt.js) - 图1

(上面这一部分本文不做探究)
对于我们而言,需要做的便是编写部署流程中的执行脚本,并进行测试,保证自动部署流程平滑进行。

部署脚本

部署脚本可以选择不同的编程语言调用系统API来编写,这里我选用Shell来编写。
关键步骤如下:

进入项目目录

  1. cd $PROJECT_PATH
  2. echo "Into path $PWD"

停止运行中的项目

  1. sudo pm2 stop $PROJECT_NAME

拉取项目代码变动

  1. sudo git reset --hard origin/master
  2. sudo git pull
  3. sudo chown -R www:www $PROJECT_PATH

安装依赖

  1. yarn
  2. # or npm insatll

运行项目

为了保证项目能够持久驻守系统,我选用了node项目管理器pm2来做项目运行支持。
不同情况下可以选择不同的工具。

  1. sudo pm2 start $PROJECT_NAME

运行日志

将上面步骤的代码进行控制台输出优化后就会变得人性化而易用,以下是我的项目部署后每次输出的日志:

  1. Deploy ShareManBoxNuxt
  2. =================================
  3. Start time : 2019-10-06 00:34:18
  4. =================================
  5. [Centos] Enter work directory
  6. Into path /www/wwwroot/ShareManNuxt
  7. =================================
  8. [Pm2] Stop running project
  9. [PM2] Applying action stopProcessId on app [shareman-box-v3](ids: 0)
  10. [PM2] [shareman-box-v3](0)
  11. ┌─────────────────┬────┬─────────┬──────┬─────┬─────────┬─────────┬────────┬─────┬────────┬──────┬──────────┐
  12. App name id version mode pid status restart uptime cpu mem user watching
  13. ├─────────────────┼────┼─────────┼──────┼─────┼─────────┼─────────┼────────┼─────┼────────┼──────┼──────────┤
  14. shareman-box-v3 0 0.33.4 fork 0 stopped 0 0 0% 0 B root disabled
  15. └─────────────────┴────┴─────────┴──────┴─────┴─────────┴─────────┴────────┴─────┴────────┴──────┴──────────┘
  16. Use `pm2 show ` to get more details about an app
  17. =================================
  18. [Git] Pull new commit
  19. HEAD is now at f0e37f1 feat: update day item style
  20. Updating f0e37f1..9c72ee8
  21. Fast-forward
  22. components/Pagination.vue | 2 +-
  23. components/Waterfall.vue | 4 +-
  24. components/item/blog.vue | 6 +-
  25. components/item/common.vue | 6 +-
  26. components/item/day-backup.vue | 4 +-
  27. components/item/day.vue | 18 +--
  28. components/item/idea.vue | 4 +-
  29. components/item/mailbox.vue | 6 +-
  30. components/item/movie.vue | 6 +-
  31. components/item/plan.vue | 8 +-
  32. components/item/project.vue | 4 +-
  33. pages/day/_date.vue | 342 ++++++++++++++++++++++++++---------------
  34. plugins/helper.js | 14 +-
  35. 13 files changed, 255 insertions(+), 169 deletions(-)
  36. =================================
  37. [Yarn] Install dependencies
  38. yarn install v1.12.3
  39. [1/4] Resolving packages...
  40. success Already up-to-date.
  41. Done in 0.80s.
  42. =================================
  43. [Yarn] Build project
  44. yarn run v1.12.3
  45. $ nuxt build
  46. Production build
  47. Builder initialized
  48. Nuxt files generated
  49. Compiling Client
  50. Client: Compiled successfully in 39.28s
  51. Compiling Server
  52. Server: Compiled successfully in 5.96s
  53. Done in 67.09s.
  54. =================================
  55. [Pm2] Start project
  56. [PM2] Applying action restartProcessId on app [shareman-box-v3](ids: 0)
  57. [PM2] [shareman-box-v3](0)
  58. [PM2] Process successfully started
  59. ┌─────────────────┬────┬─────────┬──────┬───────┬────────┬─────────┬────────┬─────┬───────────┬──────┬──────────┐
  60. App name id version mode pid status restart uptime cpu mem user watching
  61. ├─────────────────┼────┼─────────┼──────┼───────┼────────┼─────────┼────────┼─────┼───────────┼──────┼──────────┤
  62. shareman-box-v3 0 0.33.4 fork 31713 online 0 0s 0% 13.8 MB root disabled
  63. └─────────────────┴────┴─────────┴──────┴───────┴────────┴─────────┴────────┴─────┴───────────┴──────┴──────────┘
  64. Use `pm2 show ` to get more details about an app
  65. =================================
  66. [Webhook] Deploy completely
  67. =================================
  68. End time : 2019-10-06 00:35:56