使用 Hugo 搭建博客自动发布系统

本文主要介绍如何使用 Obsidian + Hugo + Gitea + Cloudflare Pages 搭建博客自动发布系统

其工作流为:

graph TD
  A[Obsidian/VSCode 写博客] --> B[提交到 Gitea]
  B --> C[Gitea Actions 使用 Hugo 构建静态页]
  C --> D[使用 Wrangler 将静态页推送到 Cloudflare Pages]
  D --> E[通过自定义域名访问]

注: 如果你使用 Github/Gitlab,可以让 Cloudflare Pages 构建而不使用 Actions 和 Wrangler

1. 软件安装#

  1. 下载 Obsidian#

  2. 下载 Hugo#

    需下载带_extended的预编译包
  3. 下载 nvm-windows#

    然后使用如下命令安装 nodejs:(使用 Cloudflare Pages 从 Github/Gitlab 构建可以跳过此步骤
    # 列出目前可用 nodejs 版本
    nvm list available
    
    # 安装指定版本 nodejs
    nvm install 24.10.0;
    
    # 使用指定版本 nodejs
    nvm use 24.10.0;

    注: nodejs 版本选用可以参考安装 Wranglernodejs 发布

  4. 在手机上安装番茄钟工具 Forest#

    防拖延、提高专注度的工具,如无需要可跳过

2. 配置 Obsidian#

2.1 创建仓库#

在你的工作目录 workdir 创建一个仓库,如:my-digital-garden

2.2 初始化 git 仓库#

cd my-digital-garden
git init

2.3 .gitignore 配置#

# 忽略 obsidian 配置目录 必须以 /* 结尾 否则不忽略规则不生效
.obsidian/*

# 追踪以下文件
!.obsidian/app.json
!.obsidian/hotkeys.json
!.obsidian/templates.json

2.4 软件设置#

2.4.1 文件与链接#

文件与链接设置

2.4.2 模板#

模板设置

2.4.3 快捷键#

快捷键设置

3. 配置 Hugo#

3.1 创建 Hugo site#

在 workdir 执行以下命令,让 Hugo 使用 Obsidian 的仓库路径

hugo new site my-digital-garden --format yaml --force

3.2 设置 Hugo 主题 book#

cd my-digital-garden
git submodule add https://git.codehub.cn.eu.org/amos/hugo-book.git themes/book`

# 将 theme: 'book' 添加到 hugo.yaml 文件

3.3 .gitignore 配置#

...

# 忽略hugo文件
*.lock
public/
_gen/

3.4 完善目录结构#

创建 Obsidian 配置中使用的目录

mkdir content/posts
mkdir assets/images

3.5 修改模板文件#

修改 archetypes/default.md 文件内容如下:

---
date: '{{date}}T{{time}}+08:00'
draft: true
title: '{{title}}'
---

3.6 图像路径映射#

追加路径映射配置到 hugo 配置文件 hugo.yaml。这样 obsidian 和 hugo 中图像的路径就统一了,如果想在 vscode 的 markdown 预览器中正确显示图片,需要图像链接以 / 开头,即:![](/assets/images/someimage.png)

[module]
  [[module.mounts]]
    source = "assets/images"
    target = "static/assets/images"

4. 本地测试预览#

4.1 新建笔记#

修改标题,使用快捷键插入模板,写入内容

4.2 在 Hugo 中预览#

hugo server -D

注: 如果你也使用 book 主题,请注意 hugo.yaml 中的 BookServiceWorker 设置,如果不需要 service worker 缓存页面和资源,建议设置为 false

5. 将静态页发布到 Cloudflare Pages#

注: 如果你选择从导入现有 Git 存储库开始,即源码托管在 Github/Gitlab 上,那么按照 Cloudflare Pages 的步骤做即可,本部分请跳过

本部分内容适用于托管在其他代码托管平台

5.1 配置 Cloudflare#

5.1.1 创建 Pages 项目#

graph TD
  A[Cloudflare Dashboard] --> B[展开计算(Workers)]
  B --> C[选择 Workers 和 Pages]
  C --> D[点击创建应用程序]
  D --> E[选择 Pages]
  E --> F[选择拖拽文件]
  F --> G[点击开始使用]
  G --> H[输入项目名称]
  H --> I[点击创建项目]

绑定自定义域名#

graph TD
  A[Workers 和 Pages] --> B[选择刚才创建的项目]
  B --> C[选择自定义域标签页]
  C --> D[点击 设置自定义域]
  D --> E[输入域名]
  E --> F[继续]
  F --> G[激活域]

等待 DNS 更新成功之后,即可通过自定义域名访问

5.1.2 创建账户 API 令牌#

graph TD
  A[Cloudflare Dashboard] --> J[展开管理账户]
  J --> B[选择账户API令牌]
  B --> C[点击创建令牌]
  C --> D[选择自定义令牌]
  D --> E[指定令牌名称]
  D --> F[权限下选择账户、Cloudflare Pages 和编辑]
  E --> G[点击继续以显示摘要]
  F --> G
  G --> H[点击创建令牌]
  H --> I[将令牌添加到 Gitea secrets(参考后续步骤)]

创建账户API令牌

5.1.3 获取账号 ID#

graph TD
  A[Cloudflare Dashboard] --> B[点击左侧菜单栏 账户主页]
  B --> C[点击已托管的域名]
  C --> D[滚动内容到最下面]
  D --> E[在右侧 API 部分找到 账户ID]
  E --> F[将账户ID 添加到 Gitea secrets(参考后续步骤)]

5.2 配置 Gitea#

graph TD
  A[登录 Gitea] --> B[转到 Gitea 用户设置]
  B --> C[在 Actions 下找到密钥]
  C --> D[添加**CLOUDFLARE_ACCOUNT_ID**,值为账号ID]
  C --> E[添加**CLOUDFLARE_API_TOKEN**,值为账户API令牌]

注: 这两个名称是 Wrangler 默认支持的,参见System environment variables · Cloudflare Workers docs

在这里理论上支持自定义的名称,只要与 workflow 中的 secrets.自定义名称 一致即可,这个没有测试

5.3 配置 CI/CD#

5.3.1 安装 Wrangler#

在项目根目录运行命令:

# 本地安装,Cloudflare 推荐方式
npm i -D wrangler@latest
npx wrangler -v

5.3.2 .gitignore 配置#

...

# 忽略nodejs
node_modules/
# package-lock.json 应该追踪,优点如下:版本一致性、确定性安装,快速安装

# 忽略wrangler
.wrangler/

5.3.3 创建 Workflow#

在项目根目录创建 .gitea/workflows/pages-deployment.yaml,内容如下:

name: Cloudflare Pages Deployment Action
run-name: Deploy by ${{ gitea.actor }}

on: [push]

jobs:
  deploy:
    runs-on: [win_x64]
    permissions:
      contents: read
      deployments: write
    name: Deploy to Cloudflare Pages
    steps:
      - name: Checkout
        uses: https://gitea.com/actions/checkout@v4
        with:
          submodules: recursive
          token: ${{ secrets.YOUR_TOKEN }} # Replace YOUR_TOKEN
  
      - name: Build
        run: npm install && hugo

      - name: Deploy
        env:
          CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
          CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}        
        run: npx wrangler pages deploy public --project-name=<PROJECT NAME> # Replace PROJECT NAME

6. 总结#

通过搭建博客自动发布系统,简化了发布博客流程,提升了写作效率,我们可以将精力更多的放到博客内容上

❤️ 如果这篇文章对你有帮助,欢迎赞助支持我继续维护 ❤️

☕ Support me ⚡ 爱发电赞助