这篇文章介绍一种将博客自动更新到 HTTP 服务器的方式。

假设你有一个 VPS 服务器,并且上面已经运行 HTTP 服务器(可以是 nginx,也可以是 caddy)。那么将 Hugo 站点提交到 GitHub 后,可以借助 GitHub Actions 将站点自动部署到 VPS 服务器,核心思路是:在 GitHub 的虚拟环境中安装 Hugo、生成静态文件,然后通过 SSH 将public目录的内容同步到你的 VPS 上

整个过程配置一次,之后你只要git push,网站都会自动更新。

下面是一个经过实践检验的自动化部署方案,包含配置步骤和完整的 YAML 代码。

1. 配置 GitHub Actions

第一步:准备工作——在 GitHub 仓库中配置密钥

为了让 GitHub Actions 能安全地登录你的 VPS,你需要将 VPS 的登录凭证存储在 GitHub 仓库的“Secrets”中。

  1. 在你的 GitHub 仓库页面,点击 SettingsSecrets and variablesActions

  2. 点击 New repository secret,添加以下两个密钥:

    • SERVER_IP:你的VPS公网IP地址(或者可解析的网址亦可)。

    • SSH_PRIVATE_KEY:你的VPS登录私钥。

      如果你没有密钥对,可以在本地通过ssh-keygen -t rsa -b 4096 -f ${private_key_path}生成:

      通过 ssh-copy-id -i ${public_key_path} $USER@$HOST,或者手动更新 VPS 对应用户的文件 ~/.ssh/authorized_keys,可以将生成的公钥添加到VPS中;

      生成的私钥则添加在 repository secret 的变量 SSH_PRIVATE_KEY 中;

      公钥添加到VPS后,通过 ssh -i ${private_key_path} $USER@$HOST 可以进行验证;

使用SSH_PRIVATE_KEY比使用密码更安全,也是社区推荐的方式。

第二步:核心配置——创建工作流文件

在你的 Hugo 项目根目录下,创建用于存放工作流定义的文件夹和文件。

mkdir -p .github/workflows
touch .github/workflows/deploy.yml

第三步:代码实现——完整的部署工作流

将以下完整的 YAML 配置复制到新创建的 deploy.yml 文件中。这个配置定义了一个自动化流水线:当你向 main 分支推送代码时,它会自动完成从构建到部署的全过程。

name: 自动部署 Hugo 博客到 VPS 🚀

# 触发条件:当向 main 分支推送代码时启动工作流
on:
  push:
    branches:
      - main  # 如果你的默认分支是 master,请改为 master

# 定义需要执行的任务
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest  # 使用最新版的Ubuntu虚拟环境
    steps:
      # 1. 检出你的博客源代码
      - name: 检出代码
        uses: actions/checkout@v3
        with:
          submodules: true  # 如果你使用了主题的 Git 子模块,需要启用
          fetch-depth: 0

      # 2. 安装 Hugo 环境(支持扩展版)
      - name: 安装 Hugo
        uses: peaceiris/actions-hugo@v2
        with:
          hugo-version: 'latest'  # 可以使用 'latest' 或指定版本如 '0.121.1'
          extended: true          # 如果你使用需要 Sass/SCSS 的主题(如 PaperMod),必须开启

      # 3. 运行 Hugo 命令,生成静态文件
      - name: 生成静态文件
        run: hugo --minify --gc --cleanDestinationDir
        # --minify: 压缩文件
        # --gc: 构建后运行一些清理任务(垃圾回收)
        # --cleanDestinationDir: 在构建前删除public目录中无用的旧文件

      # 4. 通过 SSH 将生成的 public 目录内容部署到 VPS
      - name: 部署到 VPS
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.SERVER_IP }}           # 从 Secrets 中读取 IP
          username: root                            # 你的 VPS 登录用户名(可根据实际情况修改)
          key: ${{ secrets.SSH_PRIVATE_KEY }}      # 从 Secrets 中读取 SSH 私钥
          source: "public/*"                        # 要上传的本地文件夹内容
          target: "/var/www/myblog"                 # VPS 上的目标路径(请根据你的 Caddy/Nginx 配置修改)
          strip_components: 1                        # 去除路径中的 "public" 部分,直接将文件放入目标目录

2. Github Actions 配置详解

这份配置几乎可以直接使用,但你最好根据自己的实际情况,微调以下几处:

  1. 触发分支 (branches):确认你代码推送的分支是main还是master,并相应修改。
  2. Hugo版本 (hugo-version):如果你想固定使用某个特定版本(避免因版本更新导致未知问题),可以将latest替换为具体版本号,例如0.121.1。务必开启extended: true,因为你的PaperMod主题需要此版本。
  3. VPS目标路径 (target):这是你需要重点修改的地方。路径必须与你之前在Caddy中配置的root指令指向的目录完全一致。例如,如果你的Caddyfile配置的是root * /var/www/myblog,那么这里的target就应该是/var/www/myblog

3. Github Actions 配置验证

  1. 提交并推送:将包含新工作流文件的代码推送到GitHub仓库的main分支。
  2. 查看执行日志:在GitHub仓库页面,点击 Actions 选项卡。你应该能看到一个名为“自动部署 Hugo 博客到 VPS”的工作流正在运行。点击它可以查看详细的日志输出,如果部署失败,这里会是排查问题的第一现场。
  3. 关于主题子模块:如果你之前是按照推荐方式,使用git submodule添加的PaperMod主题,那么工作流中的submodules: true参数会自动处理它,你无需额外操作。

将这份配置文件应用到你的仓库后,你就拥有了一个完全自动化的发布流水线。之后每次写完博客,只需要执行常规的git addgit commitgit push,几分钟后,你的VPS上的网站就会自动更新了。

参考资料

Host and deploy with hugo