实现效果:
当我在本地编辑器按下保存按钮的时候,博文章将同步发布到 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,没有实践。明天接着,逃。