配合 Travis CI,將 Hexo 博客自動部署到你的服務器上。 | Makito Log

配合 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 到本地#

git clone -b raw <倉庫克隆 URL> #只 Clone 出新建的 raw 分支 保留 master 分支用於部署

安裝 Node.js#

Node.js 的版本仍在不斷更新中,請至項目下載頁尋找合適系統架構的安裝包。

安裝包自帶包管理器 NPM。

Node.js 與 NPM 的版本
Node.js 與 NPM 的版本

安裝後可以在 Terminal 中查詢 Node.js 與 NPM 的版本。

安裝 Hexo#

cd ./HexoBlog #進入剛 Clone 的倉庫目錄
npm install hexo-cli -g
hexo init
npm install

NPM 出現無法連接的問題,可以嘗試更換淘寶開源 NPM 鏡像

接下來我們可以看到倉庫中的文件結構

文件結構
文件結構

使用 Travis CI#

首先我們先打開 Travis CI,可以在右上角找到使用 GitHub 登陸的按鈕。

Travis CI 首頁
Travis CI 首頁

授權完成後,你可以在左上角找到 My Repositories 一旁的加號“+”,點擊它,它就會列出你所有的倉庫,你只需要找到剛纔的 HexoBlog 並把它左側的開關打開就可以了。

添加倉庫
添加倉庫

選擇倉庫
選擇倉庫

生成 Access Token#

登錄 GitHub,在右上角頭像處進入設置。

進入設置
進入設置

在左側找到 Personal access tokens,並點擊右上角的 Generate new token

Personal access tokens
Personal access tokens

需要爲新的 Token 輸入一個名字,這裏我們就填入 Travis CI 好了。

Generate new token
Generate new token

確定生成後,Token 將顯示在頁面上,此時需要將其複製並保存好,並避免泄露。遺忘 Token 後不能找回,只能重新生成。

生成 Token
生成 Token

最後,我們還需要 生成隨機字符串,並在其中選擇一行隨機字符串,爲下文備用。

配置 Travis CI#

首先在 Travis CI 中找到已經啓用自動構建的倉庫,並在右側找到設置按鈕。

設置按鈕
設置按鈕

有兩處需要設置,首先需要啓用 Build only if .travis.yml is present 選項,以避免 master 分支被構建和陷入構建循環的問題。

另外,在下方的環境變量設置處,我們需要設置兩組變量,並注意保持 Display value in build log 禁用,以免構建日誌泄露 Token 等信息。

#需要設置的兩組變量
GitHubKEY = 上文生成的 GitHub Personal Access Token
NOTIFY_TOKEN = 上文生成的隨機字符串

設置頁面
設置頁面

在每次 Push 後,Travis CI 將檢查分支下的 .travis.yml 文件,並以此作爲配置進行構建。

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

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 了,我們接下來就介紹一下這個文件。

hexo generate #生成靜態整站
cd ./public #生成的靜態頁面會存儲在 public 目錄下
git init
git config --global push.default matching
git config --global user.email "username@example.com" #填入 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 爲例。

文件內容如下:

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 的接口,因爲它是最好的語言!很簡單,代碼如下:

<?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 中的最後一行就可以改成:

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

測試#

還記得之前的 HexoBlog 文件夾嗎?

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 的用戶來說很是方便。