利用Github上的Webhooks实现网站自动化部署

前言

由于本人的hexo博客是提交到GitHub上的,每一次更新博客都得在服务器上面手动pull更新,这样就显得十分蛋疼。所以Google了一下我的需求,发现了Github上的 Webhooks 功能,为此记录下我实现的过程。

安装依赖

由于Webhooks使用的是NodeJS,所以需要安装npm等相关的依赖。

sudo apt-get install nodejs
sudo apt-get install npm

安装webhooks后端服务所需要的组件

安装github-webhook-handler

npm i -S github-webhook-handler

安装node进程管理工具pm2

npm i -g pm2

创建自动化部署脚本文件deploy.sh

在自定义目录下创建deploy脚本实现自动化部署,内容如下:

echo "start deployment"
cd /home/xxx/xxx.github.io
git fetch --all
git reset --hard origin/master
echo "done"

运行时如果会出现:

cd: can't cd to /home/xxx/xxx.github.io

原因可能是你的shell脚本在window上编写的,这样的话到linux系统运行时就会出现编码格式问题,window为dos而linux为unix。解决: 使用vim更改文件格式。

vim deploy.sh

查看文件格式:

:set ff

更改文件格式为unix:

:set ff=unix
或者
:set fileformat=unix

创建Webhook后端运行代码

在上文deploy.sh文件同一目录下创建webhook.js文件,内容如下

var http = require('http')
var createHandler = require('github-webhook-handler')
var handler = createHandler({ path: '/auto_deploy', secret: 'xxxx' })
// 上面的 secret 在配置Github上webhook时需要用到
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) });
}
http.createServer(function (req, res) {
  handler(req, res, function (err) {
    res.statusCode = 404
    res.end('no such location')
  })
}).listen(10000)//监听本地10000端口
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);
    run_cmd('sh', ['./deploy.sh',event.payload.repository.name], function(text){ console.log(text) });
})
//deploy.sh为自动化部署的脚本文件

使用pm2进程管理器运行webhook.js

pm2 start webhook.js

如果在运行的时候如果提示 github-webhook-handler is not defined 未找到 ,可以在目录中执行 npm link github-webhook-handler。 可以使用以下命令查看端口是否正常使用:

netstat -tlnp|grep 10000

正常结果如下图: tcp

目前为止,一切顺利的话,webhook就在服务器上跑了起来,如果需要映射到公网的80端口,那么需要配置一下Nginx反向代理。

配置Nginx

配置Nginx使访问网站80端口的**/auto_deployURL转发到本地的10000端口,在/etc/nginx/nginx.conf**文件中加入如下配置:

	server
	{
	  # 80端口是http正常访问的接口
	  listen 80;
	  server_name xxx.com;
	  location /auto_deploy {
        proxy_pass http://127.0.0.1:10000;
		}
	}

重启Nginx:

sudo systemctl restart nginx.service

配置Github上的Webhook

进入Github项目地址,点击设置按钮,找到Webhooks,进行如下配置: 其中,Secret项需要和webhook.js文件中的保持一致,Content type 选择application/json。 不出意外的话可以看到最近提交是否成功。