使用webhook自动部署博客

现在写文章都是每次在本地写好后,都要去服务器上git pull 同步一下,这样比较麻烦。后来找到可以通过在GitHub添加webhook的方式实现,只要repopush操作,那么就通知服务器部署博客。 查看了很多文章,但是没有成功,可能我的环境和别人不一样,不能照着他人那样依葫芦画瓢…记录下自己的实践过程

前提

服务器系统:CentOS 7

服务器已经安装好 node/git(能ssh访问)/hexo/pm2/nginx

并且博客目录已和GitHub仓库同步(也就是在博客目录下输入git status 会显示git的信息)

文件目录:

安装github-webhook-handler

root 用户(全局安装):

npm install -g github-webhook-handler

⚠️ 我这里是用这个安装后,到博客目录下运行js还是会报找不到module的错,🤒解决办法:在博客目录再执行一次:npm install github-webhook-handler

编写代码

进入到博客deploy目录下,新建一个deploy.sh脚本(用于在收到GitHub push操作后进行pull博客代码并部署):

vim deploy.sh(不建议使用这个sh)

1
2
3
4
5
6
7
8
9
10
#!/bin/bash

WEB_PATH='/home/git/blog/public'

echo "-----start deploy-----"
cd $WEB_PATH
echo "-----pulling source code-----"
git reset --hard origin/master && git clean -f
git pull && git checkout master
echo "-----finished-----"

WEB_PATH改成博客静态页面(就是存放那些js html的目录)所在的目录,我这里是public

⚠️ 注意:上面的sh脚本会将博客仓库(我这里是public目录)已有的改动会丢弃掉,因此最好不要在博客仓库中改动文件,我之前就是在public目录下新建了deploy.shwebhook.js结果push后部署将我改动的文件给删掉了… 💢


2019-03-14 16:28 update:

上面的sh 有些问题:本地使用hexo d 将博客 pushGitHub上后webhook也显示成功了,但是访问博客还是会发现是没有更新。。。

因此将上面的sh修改下(加上了部署的耗时统计):

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash
start_time=`date --date='0 days ago' "+%Y-%m-%d %H:%M:%S"`
WEB_PATH='/home/git/blog/public'
echo "-----start deploy,StartTime: $start_time-----"
cd $WEB_PATH
echo "-----pulling source code-----"
#git reset --hard origin/master && git clean -f
#git pull && git checkout master
git pull origin master
finish_time=`date --date='0 days ago' "+%Y-%m-%d %H:%M:%S"`
duration=$(($(($(date +%s -d "$finish_time")-$(date +%s -d "$start_time")))))
echo "Time consuming: $duration"
echo "-----finished.EndTime: $finish_time-----"

这里使用的是nodejs来实现webhook服务。因此在博客deploy 目录新建一个webhook.js:

vim webhook.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var http=require('http')
var createHandler = require('github-webhook-handler')
//这里的path和secret 改成你自己想要设定的值,一会需要填写到GitHub webhooks中
var handler = createHandler({ path: '/webhooks_push', secret: 'INSERT_YOUR_SECRET' })
function run_cmd(cmd, args, callback) {
var spawn = require('child_process').spawn;
var child = spawn(cmd, args);
var resp = "";
child.stdout.on('data', function(buffer) { resp += buffer.toString(); });
child.stdout.on('end', function() { callback (resp) });
}
handler.on('error', function (err) {
console.error('Error:', err.message)
})
handler.on('push', function (event) {
console.log('Received a push event for %s to %s',
event.payload.repository.name,
event.payload.ref);
//这里是收到GitHub push操作后会执行的脚步就是上面写的
run_cmd('sh', ['./deploy.sh'], function(text){ console.log(text) });
})
try {
http.createServer(function (req, res) {
handler(req, res, function (err) {
res.statusCode = 404
res.end('no such location')
})
}).listen(7777)//监听7777端口
}catch(err){
console.error('Error:', err.message)
}

接着运行webhook node服务,我这里使用的是pm2的方式启动:

在博客目录下:

pm2 start webhook.js

不使用pm2,常规后台运行并将日志记录到webhook.log中:

nohup node webhook.js > webhook.log &

GitHub配置webhook

打开博客GitHub的repo>Settings>Webhooks>Add webhook:

填写服务器webhook的访问地址和在webhook.jssecret

最后

按理说照着上面一顿操作后,就可以实现自动化部署博客了,但是。。。我这个就是不行,不能访问,GitHub webhook 显示的是Service Timeout,后来才发现是我的服务器使用的是Nginx,没有处理转发这个请求。。。。

因此在nginx中要配置一个代理转发,然后将GitHub webhook中的链接改一下:

nginx

githubwebhook-update


参考文章:

快速搭建Hexo博客+webhook自动部署+全站HTTPS

将 Hexo 博客发布到自己的服务器上

使用Github的webhooks进行网站自动化部署