再记:现在的HUGO建站与部署
三年前,我在前文中记录了本站从动态博客迁移到 Hugo 的过程。
现在回头看,最初的思路并没有变化:
- 本地使用 Hugo 生成静态文件。
- 服务端只运行 Nginx,不安装 Hugo。
- 使用 rsync over SSH 将本地的
public/同步到服务器。
变化主要在于:站点、配置和部署脚本都已纳入 Git;主题使用 Git 子模块固定版本;部署之前还要完成一次严格构建和本地链接审计。
这样做稍显繁琐,但换一台电脑后,可以从一个空目录重新得到相同的网站。
0、准备环境 #
本地需要:
- Git
- Hugo Extended
- Python 3
- rsync
- SSH 客户端
服务端只需要 Nginx、SSH 和 rsync。
Hugo 的安装方式随发行版而异,请参阅官方安装文档。 以 Debian/Ubuntu 和 Fedora 为例:
| |
安装后先记录版本:
| |
hugo version应包含extended。也不必盲目追逐最新版本;站点能够通过完整审计的版本,
才是当前可用的版本。
1、克隆站点和主题 #
本站的主题不是普通目录,而是 Git 子模块。普通的git clone只会得到空的主题目录,
所以应当递归克隆:
| |
若仓库已经克隆,则补充执行:
| |
随后检查:
| |
每行开头不应出现-或+。-表示主题尚未初始化;+表示当前主题版本与主仓库记录不符。
Git 对这些状态的定义见git-submodule文档。
为了使一次构建可以追溯,我通常同时保留以下输出:
| |
如此便可以知道:哪一版站点、哪一版主题、由哪一版 Hugo 生成。
2、站点目录 #
当前仓库大致如下:
| |
public/是构建结果,不纳入 Git,也不视作源文件。真正需要保存的是content/、配置、
模板、资源和脚本。Hugo 各目录的作用可查阅目录结构文档。
主题子模块本身保持不变。需要修改模板时,在项目的layouts/或本站自己的主题覆盖层中
放置同路径文件。Hugo 会优先使用项目层文件;这一行为见Theme components。
这样更新官方主题时,不必处理自己留下的修改。
3、本地预览 #
先列出可用主题:
| |
默认使用 Narrow:
| |
然后访问:
| |
也可以将narrow换成typo、papermod或blowfish。预览只用于查看页面;
最终上线内容取决于部署命令指定的主题。
4、构建和审计 #
普通的hugo命令只负责生成站点。本站统一使用脚本,以免每次手写参数:
| |
audit会启用严格警告和路径检查,再检查生成的 HTML、CSS、空字段与失效本地链接。
它通过之后,public/才可用于部署。
主题或 Hugo 升级后,应检查全部主题:
| |
Hugo 的构建参数可在hugo build文档中核对。
5、准备静态服务器 #
以下配置中的域名、用户和目录均为脱敏占位值:
| |
创建发布目录,并使专用部署用户能够写入:
| |
检查并重新加载 Nginx:
| |
DNS、HTTPS证书和防火墙需按实际环境另行配置。这里的 Nginx 只负责读取静态文件;
root与try_files的行为可查阅Nginx官方文档。
6、部署 #
部署密钥不进入仓库。以下地址和路径也都是脱敏占位值,执行前必须替换:
| |
先 dry-run:
| |
确认来源目录、目标地址和文件变更均正确,再正式同步:
| |
完成后清理当前 shell 中的变量:
| |
部署脚本使用 SSH 传输,并为 rsync 启用权限收敛、部分传输、延迟更新和延迟删除。
--dry-run不会修改服务器,但仍会建立 SSH 连接。rsync 参数的确切含义以
官方手册为准。
新的环境无法仅凭 Git 仓库直接部署,是有意如此:仓库保存站点,密钥负责证明身份, 二者不应放在一起。
7、以后如何更新 #
日常拉取使用:
| |
git submodule update会恢复主仓库已经记录的主题提交,并不会自动升级主题。
若确需升级,应一次只升级一个主题,审计通过后再提交新的子模块版本。不要不加检查地
对全部主题执行git submodule update --remote。
现在的思路大致就是如此:
Git保存全部输入和版本,Hugo负责确定性构建,审计阻止明显错误,rsync只发布生成结果, Nginx只提供静态文件。
与早先相比,并没有增加新的服务器组件。只是把“我记得该怎么做”,改成了“仓库本身说明 该怎么做”。