最近把博客从 Hexo 换成了 Hugo,顺便重新设计了一下构建和部署流程。趁热乎记录一下,也方便以后自己查。

先说结论:整体流程

简单来说就是这么个事儿:

我写 Markdown → 推到 GitHub → Actions 自动编译 → 服务器拉取 → Cloudflare 加速

画个图更清楚:

本地写文章 (Markdown)
        ↓ git push
GitHub main 分支
        ↓ 触发 Actions
GitHub Actions 编译
        ↓ 生成静态文件
gh-pages 分支
        ↓ 服务器 git pull
Nginx 托管静态文件
Cloudflare CDN 缓存加速
用户访问

为啥要搞这么复杂?主要是不想每次改个错别字都要登服务器手动操作。

为啥选 Hugo

之前用的 Hexo,没啥大毛病,但有几个痒点:

  1. npm 依赖太多了。每次 CI 光装依赖就得好一会儿,偶尔还会出点版本冲突的幺蛾子
  2. 本地预览慢。文章多了之后,热更新明显变卡
  3. 想尝尝鲜。Hugo 用 Go 写的,据说快得离谱

实际用下来,确实快。本地预览基本秒开,GitHub Actions 那边构建也就几秒钟的事。

GitHub Actions:自动化构建

这是整套流程的核心。配置文件在 .github/workflows/hugo.yml,做的事情也简单:

name: Build Hugo Site

on:
  push:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: 装 Hugo
        run: |
          wget -O hugo.deb https://github.com/gohugoio/hugo/releases/...
          sudo dpkg -i hugo.deb

      - name: 拉代码
        uses: actions/checkout@v4
        with:
          submodules: recursive  # 主题是 submodule

      - name: 编译
        run: hugo --gc --minify

      - name: 推到 gh-pages
        uses: peaceiris/actions-gh-pages@v4
        with:
          publish_dir: ./public
          publish_branch: gh-pages

      - name: 顺手清一下 CDN 缓存
        run: curl -X POST "https://api.cloudflare.com/..." ...

每次 push 到 main 分支,Actions 就自动跑这一套。成功之后,编译好的静态文件就躺在 gh-pages 分支里了。

双分支策略

这个设计我挺满意的:

  • main 分支:源代码,Markdown 文件 + 主题配置
  • gh-pages 分支:编译产物,纯静态文件

好处是服务器上不用装 Hugo,直接拉 gh-pages 就能用。万一哪天想换个部署方式,也方便。

服务器这边

服务器就做两件事:

  1. 定时(或手动)从 gh-pages 拉最新的静态文件
  2. Nginx 伺候着

Nginx 配置没啥特别的,主要是加了点缓存和压缩:

server {
    listen 80;
    server_name blog.kkkk24juastin.asia;
    root /var/www/blog;
    
    # 压缩
    gzip on;
    gzip_types text/css application/javascript text/html;
    
    # 静态资源缓存久一点
    location ~* \.(css|js|png|jpg|woff2)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}

更新脚本也就几行:

#!/bin/bash
cd /var/www/blog
git fetch origin gh-pages
git reset --hard origin/gh-pages

扔 crontab 里定时跑,或者配个 webhook 触发都行。

Cloudflare 加速

最后挂了层 Cloudflare,主要图几个好处:

  1. 全球 CDN。访客能从就近节点拿缓存,不用每次都回源
  2. 免费 SSL。懒得自己折腾证书
  3. DDoS 防护。虽然我这小破站应该没人会打

不过有个坑:Cloudflare 默认不缓存 HTML 页面。对于静态博客来说这太亏了,得手动加个 Cache Rule,让它把 HTML 也缓存上。

配置好之后,访问速度从之前的 2 秒多降到了几十毫秒,效果立竿见影。

实际效果

优化前后的对比:

指标之前现在
首字节时间 (TTFB)2.28s~50ms
页面加载3.5s0.8s

主要提升来自 CDN 缓存。代码层面其实已经没啥可优化的了,瓶颈都在网络延迟。

一些碎碎念

整套流程跑下来,最爽的是真的不用操心部署了。写完文章,commit + push,等个几十秒,刷新页面就能看到更新。

当然也有不爽的地方。Hugo 的模板语法(Go Template)用起来不太顺手,文档也比较散。不过忍忍就好,毕竟主题配好了基本不用改。

如果你也在折腾博客,希望这篇能有点帮助。有问题可以留言,看到会回的 👋