前言
博客迁至VPS上,依旧用hexo生成静态网页,现在写博客的流程是:
- Cloud Studio写博客并生成
- 静态网站Push到github上的pages仓库(仓库已转私有)
- VPS上git pull
未免太麻烦了有没有…所以了解到webhook这个东西,花了一点时间把搞定了,Push上去之后VPS端就不用Pull了。
webhook原理图
略有不同的是,我这里并不是nodejs监听消息,而且不是直接将端口开放,而是用已有的nginx去做一下本地proxy。
方案
github提供了webhook功能,在Push、Tag Push、Issue、评论、合并请求等操作后,可以触发hook自动回调一个地址,用户可以自己根据不同的需求,来编写自己的脚本程序(比如发邮件,自动部署等)
depoly key生成
由于github上存放静态网站的仓库已经转为私有,所以在http方式下,git pull需要密码,这个时候就需要在仓库里设置一下depoly key用ssh方式pull了。
- 修改https方式为ssh
1 | ubuntu@ip-172-31-93-37:/var/www/blog$ git remote -v |
- 生成rsa密钥
1 | ubuntu@ip-172-31-93-37:/var/www/blog$ ssh-keygen -t rsa -f ~/.ssh/deploy_key -C example@gmail.com |
- 查看公钥
1 | ubuntu@ip-172-31-93-37:/var/www/blog$ sudo cat ~/.ssh/deploy_key.pub |
- 向config添加如下内容
1 | Host github.com |
- 把密钥填到仓库里
- 测试
1 | ubuntu@ip-172-31-93-37:/var/www/blog$ ssh -T git@github.com |
OK,我们现在可以pull了。
webhook实现
之前caddy是自带有webhook模块的,但是后面又用了nginx,所以不行。但如果自己实现一个webhook的代码又是很麻烦,所以用了GitHub上面别人的一个小wheel
配置
打开仓库的Setting-webhook-Add webhook,如下
设置图中回调地址,待会还要在nginx中修改/wbhook的proxy。
content type选择json就可以了,然后secret,根据官方文档,这里需要随机生成一个字符串,可以用如下的命令生成。
1 | ruby -rsecurerandom -e 'puts SecureRandom.hex(20)' |
这个secret有什么用呢。
每当触发了github的webhook,会向回调地址发送一个post request,header中的X-Hub-Signature是由secret与Payload做哈希运算生成的加密字符串,在服务端收到之后,可以根据secret与Payload自己生成一个签名,与header中的X-Hub-Signature做对比,这样以验证内容是否被篡改。
运行
修改一下hook服务端的配置
1 | { |
修改一下监听的地址和root,监听127.0.0.1:5000
1 | @application.route('/wbhook', methods=['GET', 'POST']) |
1 | application.run(debug=True, host='127.0.0.1', port = 5000) |
修改nginx配置,在已有的服务器配置中加入
1 | location /wbhook { |
这样访问/wbhook的request全部转发到127.0.0.1:5000上,也就可以被hook服务端接收了。
然后就可以运行了
1 | ubuntu@ip-172-31-93-37:~/python-github-webhooks$ python webhooks.py |
若一切正常,github上webhook会变绿。
处理push
当仓库中有push操作,会发来一个Request,其中Header的X-GitHub-Event值为push,处理这个就行了。
这个py脚本依旧可以处理push,它会执行/hooks/下的脚本,命名规则为:
1 | hooks/{event}-{name}-{branch} |
所以新建一个push-lyq1996.github.io-master的shell脚本,内容如下
1 | #!/bin/sh |
当然,别忘了chmod +x赋予所有者执行权限。
若一切正常,现在github上面的仓库一有push操作,这边就会自动pull了。
收尾
后台运行当然不可以忘记。
1 | nohup python webhooks.py >> ./log 2>&1 & |
这样就ok了。