本文首发于个人我的博客:高效前端项目自动化构建部署实践——使用webhook钩子运维,欢迎你们来访问哦!前端
最近访问个人博客网站的时候,我发现常常会出现打不开的状况,个人博客是搭载在coding的coding pages服务上的,仔细检查了coding服务上的代码,发现没什么毛病,应该就是coding pages的服务器不稳定形成的,因为最近在投递简历,这个状况也给我形成了必定的困扰,考虑到要给招聘者良好的浏览体验,我决定要优化一下本身的博客网站运行环境了。node
个人优化思路就是将网站文件放到我本身的服务器上。起初我打算使用Hexo的ftp部署相关的插件来完成,当我运行hexo d
的时候,文件会自动上传到服务器端,我这样试着弄了以后发现因为ftp协议的特性,在传大量的文件的时候,没法充分利用网络带宽,所以形成了速度很是慢的状况。这种状况只能将网站文件打包压缩再上传,而后在服务器端解压才能解决。想了想,我以为这样太复杂又累赘,实在是不能体现我代码洁癖的风格,拒绝拒绝!git
我在以前实习公司里,有见同事用过webhook这玩意儿,了解过其运做方法和做用。又查了一下相关资料(下为Github解释):web
Webhooks allow you to build or set up integrations, such as GitHub Apps or OAuth Apps, which subscribe to certain events on GitHub.com. When one of those events is triggered, we'll send a HTTP POST payload to the webhook's configured URL. Webhooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server. You're only limited by your imagination.shell
简单来讲就是WebHooks可用于更新外部问题跟踪器、触发CI构建、更新备份镜像,甚至部署到生产服务器。这对于我目前的需求彻底匹配呀,因而新的思路来了——在服务器端克隆下本身的博客项目并安装依赖,在coding服务上设置相应的webhook钩子,在服务器端编写接受webhook请求的回调方法,在回调方法里执行构建相关的命令。这样就不用把文件传来传去了,简洁明了,开始搞!npm
在服务器上合适的位置克隆下本身的项目文件,并安装好依赖,我这里是hexo博客项目,因此还得全局安装hexo依赖。后端
编写接收webhook回调的服务,我这里是用node.js写的,你也可使用其余后端语言,只要能执行shell命令就行。 在服务端合适的位置编写webhook.js以下:安全
const http = require('http')
const { exec } = require('child_process')
const PORT = 9999 // 服务端口
const path = '/www/wwwroot/projects/xxxxxxx/' // 这里是服务器端,此项目的文件地址
const commands = [
'cd ' + path,
'git pull',
'yarn dep', // 这个命令是我hexo项目编译的命令
'rm -rf ../../hexo-blog/', // 删除原来的文件
'mv ' + path + 'public/ ../../hexo-blog/' // 将编译的文件放入网站项目文件夹
].join(' && ') // 这里写依次要在服务器上执行的命令
var deployServer = http.createServer(function(req, res) {
if (req.url.search(/deploy\/?$/i) > 0) { // 这里作了个deploy的标记,以防用户访问此网址无心出发命令
let work = exec(commands, {
maxBuffer: 5000 * 1024, // 默认 200 * 1024
}, function(err, out) {
if (!err) {
res.writeHead(200)
res.end('Deploy Done.')
}
})
work.stdout.on('data', function(data) {
console.log('stdout: ' + data)
})
work.stderr.on('data', function(data) {
res.writeHead(500)
res.end('Server Internal Error.')
console.log('stderr: ' + data)
})
} else {
res.writeHead(404)
res.end('Not Found.')
}
})
deployServer.listen(PORT)
复制代码
代码很短很简单,重点就是要调用node的子进程来执行命令。有个坑要注意,使用子进程时,在回调函数里的打印是不会输出到控制台的,须要将当前执行过程设为一个变量,经过其stdout和stderr的data监听来获取打印输出。另外,exec在执行时会在内存中建一个buffer来缓冲组合全部的输出数据,而maxBuffer则是指定该buffer大小的属性。若是输出超过指定的大小则会报 maxBuffer exceeded 的错误,这也是很常见的错误,因此咱们须要加大其maxBuffer。bash
写好服务端代码后,咱们ssh链接服务器,执行node webhook.js
将其启动并不要关闭,以备后面调试,而且要注意你设置的端口在服务器安全组里已经打开过了,或者你也可使用Nginx反向代理到80端口开启另外一个服务,这里就不细说了,目的就是要让外网可以访问到此服务。服务器
在Git项目管理的设置里开启并设置webhook服务
http://你的服务器地址:刚才设置的端口/deploy
,令牌则是发送webhook时,客服端作的记号,也是起到防止恶意或无心请求到webhook服务的做用,若是设置了令牌,根据Git服务端的不一样,会发送不一样的令牌格式,通常是放在请求头的自定义参数里,咱们须要在服务端接收请求的方法里进行处理,这里再也不作演示。 若是设置完成,系统会自动发送检测命令来出发webhook回调。
这时咱们查看网站对应的文件,会发现已经更新了!这时设置好对应的网站服务,就能够正常访问咱们的网站了。
要注意的是,临时开启的node进程会常常本身断掉,咱们最好须要用pm2来管理node服务,PM2是node进程管理工具,能够利用它来简化不少node应用管理的繁琐任务。 全局安装pm2:
npm install -g pm2
复制代码
开启进程服务
pm2 start webhook.js
复制代码
像这样status为online就是在正常运行了
webhook会监听咱们的代码推送,因此如今只用Git推送就能够轻松地部署咱们的项目啦,大工告成!