2026-04-27 更新:当前博客发布源目录已经收敛为
jialiang-memory/Blogs/。jialiang-blog只同步这个目录,不再同步Knowledge/、Attachments/或 vault 根目录的index.md。
目标
我想要的博客系统是:
- 在 Obsidian 里写文章
- 文件通过 Syncthing 同步到 NAS 侧的
jialiang-memory - 只有
Blogs/里的内容会被发布 - push
jialiang-memory后自动触发博客构建 - 最终发布到 Cloudflare Pages
- 用自己的域名访问:
jialiang-blog.cokefly.com
核心原则是:博客内容只从 jialiang-memory/Blogs/ 来,jialiang-blog 只负责构建和部署。
当前架构
Obsidian
↓ Syncthing 同步 Markdown 文件
NAS / 本地同步目录
/Users/jialiang/jialiang-nas/jialiang-memory
└── Blogs/ # 唯一博客内容源
├── index.md # 博客首页
└── hello-world.md # 文章
↓ git push
GitHub: cjl99/jialiang-memory
↓ trigger-blog.yml 发 repository_dispatch
GitHub: cjl99/jialiang-blog
↓ deploy.yml sparse checkout Blogs/
↓ Quartz build
Cloudflare Pages: jialiang-blog
↓ Custom domain
https://jialiang-blog.cokefly.com
本地路径:
/Users/jialiang/jialiang-nas/jialiang-memory
/Users/jialiang/jialiang-nas/jialiang-blog仓库职责
| 仓库 | 角色 | 存什么 |
|---|---|---|
jialiang-memory | 内容仓库 | Obsidian vault,博客只取 Blogs/ |
jialiang-blog | 引擎仓库 | Quartz、构建脚本、Cloudflare Pages 部署流程 |
jialiang-memory/Blogs 是内容的唯一来源。jialiang-blog/content 是同步出来的 Quartz 输入目录,不应该手写长期内容。
Syncthing 同步
Syncthing 只负责把 Obsidian 文件同步到 NAS / 本地同步目录。它不负责发布,也不负责构建。
当前博客系统假设 Obsidian vault 最终同步到:
/Users/jialiang/jialiang-nas/jialiang-memory推荐规则:
- Obsidian 里写博客文章时,放进
Blogs/ - 不要把私人笔记放进
Blogs/ Blogs/index.md是博客首页- 文章文件名尽量用英文 slug,比如
hello-world.md - 文章 frontmatter 里必须有
publish: true
示例:
---
title: "Hello World"
date: 2026-04-27
tags:
- blog
publish: true
description: "A first test post from the Blogs folder."
slug: "hello-world"
---
# Hello World
正文内容。Cloudflare 和域名
域名 cokefly.com 的 DNS 已经交给 Cloudflare 管理。
Cloudflare Pages 项目:
jialiang-blogPages 默认地址:
https://jialiang-blog.pages.dev当前自定义域名:
https://jialiang-blog.cokefly.com这个自定义域名需要在 Cloudflare Pages 项目里绑定,同时 DNS 里有对应的 CNAME:
jialiang-blog.cokefly.com CNAME jialiang-blog.pages.dev注意:不要只手动加 CNAME。Cloudflare Pages 里也必须添加 custom domain,否则可能解析到了但站点不认这个域名。
发布流程
整个流程由两个 GitHub Actions workflow 串起来。
1. jialiang-memory 触发 blog 构建
文件:
.github/workflows/trigger-blog.yml只在 Blogs/** 有变化时触发:
on:
push:
branches: [main]
paths:
- "Blogs/**"这样普通笔记、日记、账号资料、附件变化都不会触发博客部署。
2. jialiang-blog 构建和部署
文件:
.github/workflows/deploy.yml收到 repository_dispatch 后,只拉取 jialiang-memory 里的 Blogs/:
- name: Checkout vault
uses: actions/checkout@v6
with:
repository: cjl99/jialiang-memory
path: ./vault
token: ${{ secrets.VAULT_TOKEN }}
sparse-checkout: |
Blogs然后同步到 Quartz:
- name: Sync blog content to Quartz
run: VAULT_PATH=./vault bash scripts/sync-blogs.sh最后构建并部署到 Cloudflare Pages:
npx quartz build
wrangler pages deploy public --project-name=jialiang-blog --commit-dirty=true --branch=main本地预览
在 jialiang-blog 仓库里运行:
cd /Users/jialiang/jialiang-nas/jialiang-blog
npm run sync:blogs
npx quartz build --serve --port 4321然后访问:
http://localhost:4321/
http://localhost:4321/hello-worldnpm run sync:blogs 会从本机的:
/Users/jialiang/jialiang-nas/jialiang-memory/Blogs同步到:
/Users/jialiang/jialiang-nas/jialiang-blog/content日常发布步骤
流程稳定后,日常只需要动 jialiang-memory。
- 在 Obsidian 里新建文章到
Blogs/ - 确认 frontmatter 有
publish: true - 等 Syncthing 同步到 NAS / 本地同步目录
- 在
jialiang-memory里提交并 push - GitHub Actions 自动触发
jialiang-blog - Cloudflare Pages 自动更新线上站点
常用命令:
cd /Users/jialiang/jialiang-nas/jialiang-memory
git status
git add Blogs
git commit -m "blog: add <post-name>"
git push origin main需要的 Secrets
jialiang-memory 仓库:
BLOG_DISPATCH_TOKEN用途:向 cjl99/jialiang-blog 发送 repository_dispatch。
jialiang-blog 仓库:
VAULT_TOKEN
CLOUDFLARE_API_TOKEN
CLOUDFLARE_ACCOUNT_ID用途:
VAULT_TOKEN:让 blog workflow 克隆 private 的jialiang-memoryCLOUDFLARE_API_TOKEN:部署 Cloudflare PagesCLOUDFLARE_ACCOUNT_ID:指定 Cloudflare 账号
踩过的坑
1. Cloudflare Pages 项目要先创建
wrangler pages deploy 不会自动创建项目,需要提前在 Cloudflare Dashboard 或 API 里建好 jialiang-blog。
2. Custom domain 要在 Pages 项目里绑定
jialiang-blog.cokefly.com 不能只靠 DNS CNAME。必须在 Cloudflare Pages 的 Custom domains 里添加这个域名。
3. Workflow 不能被 disable
jialiang-blog 的 Build and Deploy Quartz workflow 必须保持 enabled。之前 workflow 被手动 disable 后,jialiang-memory 虽然成功发了 dispatch,但 blog 没有真正部署。
4. 首页必须最终落到 content/index.md
Quartz 的首页是 content/index.md。现在首页写在 Blogs/index.md,同步脚本把 Blogs/ 内容复制到 content/ 根目录,所以最终会得到正确的首页。
5. 不要把整个 vault 复制到 Quartz
不要复制整个 jialiang-memory。那样会把账号资料、工作笔记、附件、配置文件都带进 blog 构建环境。当前方案只同步 Blogs/,并且 GitHub Actions 用 sparse checkout 限定只拉 Blogs/。
6. 不要在 .gitignore 中忽略 content/
Quartz 内部会读取 .gitignore。如果写了:
content/*
!content/.gitkeepQuartz 可能会直接扫描不到文章,构建出一个空站点。
当前规则是:jialiang-blog 保留 content/,但内容来源必须是 scripts/sync-blogs.sh 从 jialiang-memory/Blogs 同步出来的。
当前效果
线上地址:
现在这套系统的边界比较清楚:
- Syncthing:负责文件同步
- Obsidian:负责写作
jialiang-memory/Blogs:负责内容源jialiang-blog:负责 Quartz 构建- GitHub Actions:负责自动化
- Cloudflare Pages:负责托管
- Cloudflare DNS:负责域名