开发者社区> martyp> 正文

利用Git Webhooks实现jekyll博客自动化部署

简介: 这篇博客记录了搭建自动化jekyll博客部署的过程,主要结合的技术有Git Webhooks,轻量级Web框架Flask。
+关注继续查看

Automated Deployment of Jekyll Blog with Git Webhooks and Flask

在我之前的一篇博客中说到购置了一台阿里云的轻量级应用服务器并讲述了如何配置Nginx反向代理转发Disqus请求。在完成所有配置后,我发现这条路子还是走不通,原因在于原本托管在github上的jekyll博客采用git pages自动部署的,使用的是https协议,而Nginx这端如果想配置SSL必须在阿里云上绑定域名并购买相应的证书服务。心想,既然域名,证书,VPS都齐全了,不如直接将博客部署在VPS上。部署的过程比较简单,这里不再赘述,给出一篇参考博客
博客迁移完成后,我意识到更新代码是一个巨繁琐的过程:在本地更新了代码或博客,push到远程分支,ssh登录到服务器,从远程分支pull最新代码,接着jekyll build,最后将生成的_site文件夹拷贝到指定目录。这一套组合拳下来,也是有点繁琐的。
这篇博客记录了搭建自动化jekyll博客部署的过程,主要结合的技术有Git Webhooks,轻量级Web框架Flask。这里假设你已经具备基础的Nginx部署知识,可参考反向代理的搭建

什么是Git Webhooks?

Git Webhooks允许服务器接收有关对git仓库执行操作的通知,并允许用户指定服务器在接收到通知时应该执行的操作。一般来说,如果我想通过更改git触发远程操作,webhooks是一个不错的选择。在我们的例子中,我们只对push事件感兴趣(任何时候推送代码到远程仓库)。

创建一个Github Webhook

如果你的网站托管在Github上,进入Repo -> Settings -> Webhooks并点击Add Webhook
add_webhook

在上图的页面中,你需要配置在某些操作发生时由Github调用的URL。这里我们还需要在服务器上部署一个简单的应用来处理Github的Post请求,下一小节将会讲到。Content type可选json,但这里我对payload并不是很感兴趣,故采用默认的form-urlencoded。另外还可以提供一个密码。其SHA-1哈希值将添加到X-Hub-Signature中。更多细节可以参见Git Webhooks的官方文档。完成配置后点击Add webhook即可。

部署Flask应用

上一小节中,我们为博客repo创建了一个webhook,每次推送新代码到repo时,Github都会给我们的服务器发送一个POST请求,所以我们必须部署一个应用来处理该请求并重新构建jekyll。这里我不想使用一个比较重的web框架,因为我需要的仅仅是来自Github的一个通知。目前也有许多的轻量级Web框架,笔者选了Flask。在/var/www/目录下新建应用文件夹:

mkdir autorebuild -p
cd autorebuild

在安装flask之前安装虚拟环境virtualenv,进入目录创建新的python环境并激活:

pip install virtualenv
virtualenv venv
source /venv/bin/activate

使用pip安装Flask

pip install flask

现在我们可以创建一个简单的处理webhook配置中指定请求的flask应用:

from flask import Flask
import subprocess
import os

app = Flask(__name__)

@app.route('/rebuid', methods=['POST'])
def autobuildjekyll():
    script_path = "/var/www/autorebuild/jekyll_rebuild.sh"
    subprocess.call([os.path.expanduser(script_path)])
    return "Success"

if __name__ == "__main__":
    app.run()

上面的python代码(假设为refresh.py)创建了一个简单的flask应用,其中的一个endpoint(/rebuild)处理Git Webhook发来的POST请求。具体来说,autobuildjekyll函数调用一个简单的shell脚本。
jekyll_rebuild.sh脚本从Git仓库中拉取最新的修改,之后重建我们的站点:

#!/bin/bash
echo "Pulling latest from Git"
cd ~/hybridtheory/ && git pull

echo "Building Jekyll Site";
jekyll build --source ~/hybridtheory/ --destination /var/www/hytheory.com/ --incremental;
echo "Jekyll Site Built";

这里需要注意的是,千万不要省略shell脚本的头部#!/bin/bash,否则subprocess.call()会报如下错误:OSError: [Errno 8] Exec format error
直接运行python refresh.py即可启动应用,默认绑定端口5000。由于我们采用Nginx作为博客的代理服务器,简单的启动一个flask应用是不够的,我们需要使用Gunicorn来启动flask应用。
Gunicorn是一个Python wsgi http server,来源于Ruby的Unicorn项目,能够与各种wsgi web框架写作,比如Flask。首先进入虚拟环境安装Gunicorn:

pip install gunicorn

用gunicorn启动我们的flask应用:

gunicorn -b 127.0.0.1:8001 refresh:app

这里我们绑定localhost的8001端口,仅能内部访问。refresh为python文件的名字,app为应用名字。
最后我们修改Nginx配置,由于Github发送的是https请求,故我们绑定端口443。具体修改过程不再赘述,这里贴出Nginx的具体配置:

server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name www.hytheory.com;
        return 301 https://$server_name$request_uri;
}

server {
        listen 443 default_server;
        listen [::]:443 default_server;

        ssl on;
        ssl_certificate /etc/nginx/sslcert/1613132_www.hytheory.com.pem;
        ssl_certificate_key /etc/nginx/sslcert/1613132_www.hytheory.com.key;

        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;

        root /var/www/hytheory.com;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;

        server_name hytheory.com www.hytheory.com;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }
        location /refresh {
                proxy_pass http://127.0.0.1:8001;
                proxy_set_header Host $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

至此,所有的配置完成,测试成功。
原文链接:https://www.hytheory.com/tutorial/blog/deploy-jekyll-site-automatically-with-git-webhook/

参考博客

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
Git 进阶系列 | 3. 基于 Pull Request 实现更好的协作
Git 进阶系列 | 3. 基于 Pull Request 实现更好的协作
63 0
Linux:expect实现自动拉取git代码
Linux:expect实现自动拉取git代码
130 0
Git 实现连接 Github 远程仓库、拉取、推送本地文件
本地写的代码想推送到 Github 上面,可以借助 Git 命令实现,总结起来简单好用,阅读教程之前请确保你已经安装好 Git 软件;
146 0
【Linux】搭建Git后使用钩子实现代码自动部署
【Linux】搭建Git后使用钩子实现代码自动部署
155 0
Postman+Newman+Git+Jenkins实现接口自动化测试持续集成
做接口测试的话,首先要考虑的是如何选择一个合适的工具?在忽略工具是否好用,是否能满足业务要求的前提下,需要考虑以下2点: 1、要考虑工具的学习成本 2、要考虑团队的协作
255 0
IntelliJ IDEA绑定GitHub实现代码版本控制实例演示,IDEA上传、更新、同步项目到GitHub演示,Git的下载与安装
IntelliJ IDEA绑定GitHub实现代码版本控制实例演示,IDEA上传、更新、同步项目到GitHub演示,Git的下载与安装
147 0
Git 技术篇 - 本地Git绑定GitHub实现代码云寄存实例演示
Git 技术篇 - 本地Git绑定GitHub实现代码云寄存实例演示
94 0
Google 开源的 Python 命令行库:fire 实现 git 命令
涉及的示例代码和历史文章,已同步更新到 HelloGitHub-Team 仓库 一、前言 在前面三篇介绍 fire 的文章中,我们全面了解了 fire 强大而不失简洁的能力。按照惯例,我们要像使用 argparse、docopt 和 click 一样使用 fire 来实现 git 命令。 本文的关注点并不在 git 的各种命令是如何实现的,而是怎么使用 fire 去打造一个实用命令行程序,代码结构是怎样的。因此,和 git 相关的操作,将会使用 gitpython 库来简单实现。 为了让没读过 使用 xxx 实现 git 命令(xxx 指 argparse、docopt 和 click)
85 0
Git设置分支保护实现CodeReview卡点
GIT是一个分布式版本控制系统的软件,主要用来控制代码的版本。所谓分布式也就是每一个git的客户端都有一份完成的代码库,这样如果中央服务器出现问题,代码也会在各个开发者的电脑上有备份。(本文以下内容以GitLab为例)
428 0
+关注
martyp
区块链 分布式系统
文章
问答
视频
文章排行榜
最热
最新
相关电子书
更多
百度万人研发团队 Git 工具链建设的挑战与思考
立即下载
华为Git实践:工作模式创新,及多中心分布式架构
立即下载
百度万人研发团队Git工具链建设的挑战与思考
立即下载
相关实验场景
更多