實(shí)現(xiàn)效果:
當(dāng)我在本地編輯器按下保存按鈕的時(shí)候,博文章將同步發(fā)布到 Github、Coding以及我的全部服務(wù)器。
這種多節(jié)點(diǎn)發(fā)布教程,在網(wǎng)上其實(shí)很多,都是使用持續(xù)構(gòu)建部署來實(shí)現(xiàn)的。之前我也試過 Travis CI 這種工具,包括依靠 Daocloud 容器持續(xù)構(gòu)建等等,響應(yīng)速度實(shí)在是不能算快。
所以本文并不是一篇“基于持續(xù)構(gòu)建”的 Hexo 部署教程。這一次另辟蹊徑用
inotifywait 來實(shí)現(xiàn)自動發(fā)布。
流程如下:
- 本地寫完文章
- Nextcloud 同步到服務(wù)器 VPS_1
- 在 VPS_1 待命的 inotifywait 腳本監(jiān)測到文件夾變動
- 啟動 Docker 容器執(zhí)行頁面構(gòu)建
- 發(fā)布到 Github 和 Coding
- 各節(jié)點(diǎn)服務(wù)器收到變動通知,主動拉取 Github 更新
這里面只有第一步是需要自己動手的,其他全部都是自動觸發(fā)。這里的上傳服務(wù)器我選擇 Nextcloud,相關(guān)部署教程可以看我之前的文章,或者你使用其他辦法上傳本地文章。

準(zhǔn)備工具
用到的工具:inotifywait + Docker + Caddy
- inotifywait 負(fù)責(zé)監(jiān)測文件變動,然后調(diào)用 Docker
- Docker 負(fù)責(zé)構(gòu)建博客靜態(tài)頁面,并且推送到 Github
- Caddy 負(fù)責(zé)同步 Github 倉庫到各個(gè)服務(wù)器。
1. 構(gòu)建 Hexo 鏡像
一個(gè) node 和 Hexo 的鏡像大概不用很復(fù)雜。
首先確認(rèn) Hexo 需要哪些數(shù)據(jù)卷,source 目錄是文章的存儲地方,必須掛載;經(jīng)常修改主題的話,themes 也是必須掛載;public 這個(gè)文件夾作為唯一輸出,也是需要掛載的。
所以就有 source、themes 作為“輸入型”數(shù)據(jù)卷,public 作為輸出型數(shù)據(jù)卷。
Dockerfile 也就很簡單了:
FROM mhart/alpine-node
WORKDIR /hexo
RUN apk add --update --no-cache git openssh && \
npm install hexo-cli -g && \
hexo init . && \
npm install && \
rm -rf /tmp/*
# 插件
RUN npm install --save hexo-generator-sitemap
RUN npm install --save hexo-generator-feed
RUN npm install --save hexo-deployer-git
RUN npm install --save hexo-renderer-jade
RUN npm install --save hexo-generator-archive
VOLUME ["/hexo/source", \
"/hexo/themes", \
"/hexo/public", \
"/root/.ssh", \
"/root/.gitconfig"]
EXPOSE 4000
CMD ["hexo", "g"]
因?yàn)樾枰詣硬渴穑?ssh 以及 .gitconfig 這兩個(gè)文件(夾)也是必須掛載的。
直接構(gòu)建吧,還好不算很大。
2. 設(shè)置服務(wù)器文件夾監(jiān)聽
服務(wù)器監(jiān)聽的文件夾是 source 和 themes,此外,配置文件 _config.yml 也是需要監(jiān)聽的,雖然改動很少。
下面是我的腳本:
#!/bin/sh
# 設(shè)置監(jiān)聽文件夾
VOLUMES="source themes _config.yml"
# 設(shè)置監(jiān)聽動作
INOTIFY_EVENTS="create,delete,modify,move"
# 設(shè)置監(jiān)聽參數(shù)
INOTIFY_OPTONS='--monitor --exclude=~'
# 循環(huán)監(jiān)聽
inotifywait -rqe ${INOTIFY_EVENTS} ${INOTIFY_OPTONS} ${VOLUMES} | \
while read -r notifies;
do
echo "文件有變動:"
echo "$notifies"
echo "容器正在執(zhí)行頁面構(gòu)建:"
docker run --rm -t \
-v ~/同步/博客/_config.yml:/hexo/_config.yml \
-v ~/同步/博客/public:/hexo/public \
-v ~/同步/博客/source:/hexo/source \
-v ~/同步/博客/themes:/hexo/themes \
-v ~/.ssh:/root/.ssh \
-v ~/.gitconfig:/root/.gitconfig \
-p 4000:4000 zuolan/hexo hexo d -g
echo "新的頁面構(gòu)建完成。"
done
需要改動的也就數(shù)據(jù)卷那里。在后臺執(zhí)行:
nohup blog.sh &
這一部分內(nèi)容看起來就這些,實(shí)際上你要做的事情有很多,比如:
- 你需要安裝 inotifywait 這個(gè)工具,使用
sudo apt install inotify-tools安裝即可; - 如果你第一次使用 git,需要設(shè)置 .gitconfig 文件;
- 因?yàn)槭亲詣油扑?,需要設(shè)置無密碼 push 操作,準(zhǔn)備 id_rsa 和 id_rsa.pub 這兩個(gè)文件,其中公鑰放到 Github 中,私鑰掛載到容器中;
- 還有域名綁定,Coding.net 和 Github 的設(shè)置不是完全一樣,這些自己去看就好。
3. Caddy 自動 pull 到各個(gè)節(jié)點(diǎn)服務(wù)器
這里用到的 Caddy 工具是一個(gè)用 Go 語言編寫的 Web 服務(wù)器,我們需要用到的功能就是自動 pull:https://caddyserver.com/docs/git
配置格式如下:
git git@github.com:user/site {
hook /webhook secret-password
}
首先在 Github 倉庫中的設(shè)置中開啟 webhook,然后在所有子節(jié)點(diǎn)安裝上面那個(gè)工具。
所有節(jié)點(diǎn)安裝好麻煩啊,所以用 Docker 集群去干吧。Caddy 有很多 Docker 鏡像,我們拿來用就好。
首先創(chuàng)建一個(gè) Docker 集群,以前我寫過 Swarm 的文章,可以翻來參考。
然后啟動一套服務(wù),全部節(jié)點(diǎn)部署 Caddy 容器,然后它們就會處于待命狀態(tài)。
一旦本地寫完文章,服務(wù)器構(gòu)建頁面并推送到 Github,Github 會發(fā)送一個(gè)通知給 Caddy 服務(wù)器,各節(jié)點(diǎn)服務(wù)器就會自動 pull 倉庫的靜態(tài)文件到其本地。
如此全部部署完成。
以上的第三部分為個(gè)人 YY,沒有實(shí)踐。明天接著,逃。