配合 Travis CI,将 Hexo 博客自动部署到你的服务器上。

这篇教程将指导你如何将写好的文章通过 Git 提交至 GitHub 仓库,并使用 Travis CI 自动构建、部署到你的服务器上。

今年夏天的时候,为了多练习 Python,于是用就它写了一个简单的静态博客生成器,有模板有标签,不过与现有的静态博客相比还是相形见绌。即不易管理,也总出现 BUG。

博客是需要静下心来写的,程序总需要维护实在不是长计,于是,昨天我便把博客换成了 Hexo。终于可以安静的写博客了。

Hexo 是一个基于 Node.js 的博客框架,从模板、主题再到插件应有尽有,写好文章后可以得到一个静态整站,对于像个人博客这种更新需求不大的网站是再适合不过了。

网上给出的教程多是将博客托管于 GitHub Pages 上,然而 GitHub Pages 在国内部分地区以及部分运营商的网络下的表现有时并不完美,经常出现载入缓慢,CSS 及 JS 无法载入的问题,因此也有部分人选择将博客放在自己的服务器上。

但是在个人服务器上搭建博客又要考虑一个非常重要的问题——备份数据。 GitHub 提供的版本控制功能非常强大,但是个人服务器上大都没有使用版本控制系统,需要自行备份。

为什么不把 GitHub 的强大版本控制功能与个人服务器的访问速度结合在一起呢?

注意

本教程并不是为初学者准备的,因为其需要的步骤较多且较复杂,需要读者有使用 Git 及 GitHub 的经验,并了解 PHP 及 Bash。

新的开始

新建一个代码仓库,我们暂且取名为 HexoBlog 好了。
为了使仓库更简洁,我们可以在 master 分支的基础上新建一个分支,暂且取名为 raw 分支。

Clone 到本地

1
git clone -b raw <仓库克隆 URL> #只 Clone 出新建的 raw 分支 保留 master 分支用于部署

安装 Node.js

Node.js 的版本仍在不断更新中,请至项目下载页寻找合适系统架构的安装包。

安装包自带包管理器 NPM。

安装后可以在 Terminal 中查询 Node.js 与 NPM 的版本。

安装 Hexo

1
2
3
4
cd ./HexoBlog #进入刚 Clone 的仓库目录
npm install hexo-cli -g
hexo init
npm install

NPM 出现无法连接的问题,可以尝试更换淘宝开源 NPM 镜像

接下来我们可以看到仓库中的文件结构

使用 Travis CI

首先我们先打开 Travis CI,可以在右上角找到使用 GitHub 登陆的按钮。

授权完成后,你可以在左上角找到 My Repositories 一旁的加号“+”,点击它,它就会列出你所有的仓库,你只需要找到刚才的 HexoBlog 并把它左侧的开关打开就可以了。

生成 Access Token

登录 GitHub,在右上角头像处进入设置。

在左侧找到 Personal access tokens,并点击右上角的 Generate new token

需要为新的 Token 输入一个名字,这里我们就填入 Travis CI 好了。

确定生成后,Token 将显示在页面上,此时需要将其复制并保存好,并避免泄露。遗忘 Token 后不能找回,只能重新生成。

最后,我们还需要 生成随机字符串,并在其中选择一行随机字符串,为下文备用。

配置 Travis CI

首先在 Travis CI 中找到已经启用自动构建的仓库,并在右侧找到设置按钮。

有两处需要设置,首先需要启用 Build only if .travis.yml is present 选项,以避免 master 分支被构建和陷入构建循环的问题。

另外,在下方的环境变量设置处,我们需要设置两组变量,并注意保持 Display value in build log 禁用,以免构建日志泄露 Token 等信息。

1
2
3
#需要设置的两组变量
GitHubKEY = 上文生成的 GitHub Personal Access Token
NOTIFY_TOKEN = 上文生成的随机字符串

在每次 Push 后,Travis CI 将检查分支下的 .travis.yml 文件,并以此作为配置进行构建。

下面是我所使用的 .travis.yml:

1
2
3
4
5
6
7
8
9
10
11
12
13
language: node_js
node_js:
- "0.12"
install:
- npm install hexo-cli -g
- npm install hexo --save
- npm install
script:
- chmod +x ./build.sh
- ./build.sh > /dev/null
branches:
only:
- raw

有关于 Travis CI 配置的详细解释可以查阅官方文档

在这里,配置文件限制了自动构建工作只会在 raw 分支下进行。

可能你已经发现配置中的 build.sh 了,我们接下来就介绍一下这个文件。

1
2
3
4
5
6
7
8
9
10
hexo generate #生成静态整站
cd ./public #生成的静态页面会存储在 public 目录下
git init
git config --global push.default matching
git config --global user.email "[email protected]" #填入 GitHub 的邮箱地址
git config --global user.name "username" #填入 GitHub 的用户名
git add --all .
git commit -m "Travis CI Auto Builder" #自动构建后的内容将全部以此信息提交
git push --quiet --force https://${GitHubKEY}@github.com/你的GitHub用户名/你的代码仓库名.git master #自动构建后的内容将全部以此信息提交
curl --connect-timeout 20 --max-time 30 -s http://远端服务器URL/webhook.php?_=${NOTIFY_TOKEN} #服务器 Webhook 将在下文介绍

远端服务器的配置

到这里,大部分的工作都完成了,我们只需要配置远端服务器就可以了。

远端服务器所需要做的工作便是将构建好的内容同步到本地,在这之前,我们每次提交到 raw 分支的新文章会被 Travis CI 取得并生成整站,再由 Travis CI 将整站 Push 回 master 分支。

因此我们只需要通知远端服务器 Clone 一下 master 分支就可以了。

首先我们在服务器上新建一个 Bash 文件,我使用的是 VPS,因此以保存在 /home/sync_blog.sh 为例。

文件内容如下:

1
2
3
4
cd /var/www/blog/ #进入网站的根目录 假设 blog 文件夹是 blog 子域名的根目录
rm -rf ./_ > /dev/null #清理上次的文件
rm -rf ./._ > /dev/null #清理上次的文件
git clone --depth=50 --branch=master https://github.com/SumiMakito/SumiMakito.github.io.git ./ #从 master 分支 Clone

下一步,创建一个用 PHP 实现的类似于 Webhook 的接口,因为它是最好的语言!很简单,代码如下:

1
2
3
4
5
6
7
8
<?php
if($_GET['_']=="上文的随机字符串") {
shell_exec("/home/sync_blog.sh > /dev/null");
print("Done!");
} else {
die("Invalid token!");
}
?>

假设这个 PHP 页面可以从 http://www.example.com/webhook.php 访问到,那么上文中 build.sh 中的最后一行就可以改成:

1
curl --connect-timeout 20 --max-time 30 -s http://www.example.com/webhook.php?_=${NOTIFY_TOKEN} #服务器 Webhook 将在下文介绍

测试

还记得之前的 HexoBlog 文件夹吗?

1
2
3
4
5
6
cd ./HexoBlog
hexo new hello-ci #本地没有 Hexo 的话可以直接跳过这一步
vim ./source/_posts/hello-ci.md
git add --all .
git commit -m "Hello, CI!"
git push

结语

这篇教程稍麻烦一些,但是也能帮助你了解 Travis CI 是如何简单配置并工作的。

在本地也可以生成整站,但这种方案对于本地无法安装 Node.js 及 Hexo 的用户来说很是方便。