實現效果:
當我在本地編輯器按下保存按鈕的時候,博文章將同步發布到 Github、Coding以及我的全部服務器。
這種多節點發布教程,在網上其實很多,都是使用持續構建部署來實現的。之前我也試過 Travis CI 這種工具,包括依靠 Daocloud 容器持續構建等等,響應速度實在是不能算快。
所以本文并不是一篇“基于持續構建”的 Hexo 部署教程。這一次另辟蹊徑用
inotifywait 來實現自動發布。
流程如下:
- 本地寫完文章
- Nextcloud 同步到服務器 VPS_1
- 在 VPS_1 待命的 inotifywait 腳本監測到文件夾變動
- 啟動 Docker 容器執行頁面構建
- 發布到 Github 和 Coding
- 各節點服務器收到變動通知,主動拉取 Github 更新
這里面只有第一步是需要自己動手的,其他全部都是自動觸發。這里的上傳服務器我選擇 Nextcloud,相關部署教程可以看我之前的文章,或者你使用其他辦法上傳本地文章。
準備工具
用到的工具:inotifywait + Docker + Caddy
- inotifywait 負責監測文件變動,然后調用 Docker
- Docker 負責構建博客靜態頁面,并且推送到 Github
- Caddy 負責同步 Github 倉庫到各個服務器。
1. 構建 Hexo 鏡像
一個 node 和 Hexo 的鏡像大概不用很復雜。
首先確認 Hexo 需要哪些數據卷,source 目錄是文章的存儲地方,必須掛載;經常修改主題的話,themes 也是必須掛載;public 這個文件夾作為唯一輸出,也是需要掛載的。
所以就有 source、themes 作為“輸入型”數據卷,public 作為輸出型數據卷。
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"]
因為需要自動部署,.ssh 以及 .gitconfig 這兩個文件(夾)也是必須掛載的。
直接構建吧,還好不算很大。
2. 設置服務器文件夾監聽
服務器監聽的文件夾是 source 和 themes,此外,配置文件 _config.yml 也是需要監聽的,雖然改動很少。
下面是我的腳本:
#!/bin/sh
# 設置監聽文件夾
VOLUMES="source themes _config.yml"
# 設置監聽動作
INOTIFY_EVENTS="create,delete,modify,move"
# 設置監聽參數
INOTIFY_OPTONS='--monitor --exclude=~'
# 循環監聽
inotifywait -rqe ${INOTIFY_EVENTS} ${INOTIFY_OPTONS} ${VOLUMES} | \
while read -r notifies;
do
echo "文件有變動:"
echo "$notifies"
echo "容器正在執行頁面構建:"
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 "新的頁面構建完成。"
done
需要改動的也就數據卷那里。在后臺執行:
nohup blog.sh &
這一部分內容看起來就這些,實際上你要做的事情有很多,比如:
- 你需要安裝 inotifywait 這個工具,使用
sudo apt install inotify-tools
安裝即可; - 如果你第一次使用 git,需要設置 .gitconfig 文件;
- 因為是自動推送,需要設置無密碼 push 操作,準備 id_rsa 和 id_rsa.pub 這兩個文件,其中公鑰放到 Github 中,私鑰掛載到容器中;
- 還有域名綁定,Coding.net 和 Github 的設置不是完全一樣,這些自己去看就好。
3. Caddy 自動 pull 到各個節點服務器
這里用到的 Caddy 工具是一個用 Go 語言編寫的 Web 服務器,我們需要用到的功能就是自動 pull:https://caddyserver.com/docs/git
配置格式如下:
git git@github.com:user/site {
hook /webhook secret-password
}
首先在 Github 倉庫中的設置中開啟 webhook,然后在所有子節點安裝上面那個工具。
所有節點安裝好麻煩啊,所以用 Docker 集群去干吧。Caddy 有很多 Docker 鏡像,我們拿來用就好。
首先創建一個 Docker 集群,以前我寫過 Swarm 的文章,可以翻來參考。
然后啟動一套服務,全部節點部署 Caddy 容器,然后它們就會處于待命狀態。
一旦本地寫完文章,服務器構建頁面并推送到 Github,Github 會發送一個通知給 Caddy 服務器,各節點服務器就會自動 pull 倉庫的靜態文件到其本地。
如此全部部署完成。
以上的第三部分為個人 YY,沒有實踐。明天接著,逃。