从零搭建一个 Obsidian 博客

这是本博客的第一篇文章,也是一份面向新手的完整搭建记录。

这套方案把写作、版本管理和网站部署拆成几个清晰的部分:

  • Obsidian:写文章和整理笔记
  • Quartz:把 Markdown 生成博客页面
  • Git:记录每次修改
  • GitHub:保存项目代码
  • Cloudflare Pages:自动构建并发布网站

最终的工作流是:

Obsidian 写作

博客项目中的 Markdown
    ↓ git push
GitHub 仓库
    ↓ 自动构建
Cloudflare Pages

公开网站

它的核心优点是:文章一直是本地 Markdown 文件,不依赖某个网站后台。以后即使更换博客引擎,内容也仍然可以继续使用。

一、准备工具和账号

开始之前,需要准备以下内容:

  1. 一个完成邮箱验证的 GitHub 账号,用于保存博客仓库。
  2. 一个 Cloudflare 账号,用于使用 Pages 部署网站。
  3. Obsidian,用于写作。
  4. Git,用于提交和推送代码。
  5. Node.js 22 或更高版本,用于运行 Quartz。
  6. 一个终端工具,例如 macOS 的 Terminal、Windows Terminal 或 Linux Shell。

Git 和 Node.js 安装好之后,先检查版本:

git --version
node --version
npm --version

macOS 如果还没有 Git,可以运行:

xcode-select --install

Node.js 可以从 Node.js 官网 安装。当前 Quartz 项目要求 Node.js 22 或更高版本,版本太低可能导致本地安装和 Cloudflare 构建失败。

建议给 GitHub 账号开启双重验证,并提前决定一个公开仓库名称,例如:

yourname/my-blog

博客仓库只放准备公开的内容,不要直接把包含私人笔记的整个 Obsidian Vault 上传到 GitHub。

二、建立项目和 GitHub 仓库

1. 创建 Quartz 项目

Quartz 是一个支持 Obsidian Flavored Markdown 的静态网站生成器,支持双链、标签、Callout、目录、搜索、反向链接和图片。

可以先参考 Quartz 官方文档,然后在自己的项目目录中执行:

git clone https://github.com/jackyzha0/quartz.git my-blog
cd my-blog
npm install

这里的 my-blog 只是示例项目名,可以改成自己的名字。假设项目放在:

~/Projects/my-blog

这个路径只是通用示例,实际可以放在任何自己管理代码的目录中。

2. 连接自己的 GitHub 仓库

在 GitHub 中创建一个空仓库。第一次创建时,建议不要自动添加 README、License 或 .gitignore,避免和本地项目产生冲突。

如果本地项目最初是从 Quartz 官方仓库克隆的,可以把官方仓库保留为 upstream,再把自己的仓库设置为 origin:

git remote rename origin upstream
git remote add origin git@github.com:yourname/my-blog.git
git remote -v

第一次提交:

git add .
git commit -m "初始化博客项目"
git branch -M main
git push -u origin main

Git 需要知道提交者是谁。第一次使用时配置:

git config --global user.name "你的名字"
git config --global user.email "你的 GitHub 邮箱"

3. 配置 GitHub 认证

推荐使用 SSH。生成密钥:

ssh-keygen -t ed25519 -C "你的 GitHub 邮箱"

然后复制公钥:

macOS:

pbcopy < ~/.ssh/id_ed25519.pub

Linux:

cat ~/.ssh/id_ed25519.pub

Windows 可以打开用户目录下的 .ssh/id_ed25519.pub 文件。

把公钥添加到 GitHub 的 Settings → SSH and GPG keys → New SSH key,最后测试:

ssh -T git@github.com

如果不使用 SSH,也可以使用 HTTPS,但需要配置凭据或 GitHub Personal Access Token。

三、整理内容目录,让 Obsidian 只编辑公开内容

Quartz 项目中真正需要写文章的部分,是内容目录。可以整理成这样:

my-blog/
├── content/                # 公开内容目录
│   ├── index.md            # 首页
│   ├── posts/              # 文章
│   ├── pages/              # 关于页等固定页面
│   └── assets/             # 公共图片和资源
├── quartz/                 # Quartz 核心代码
├── quartz.config.ts        # 网站配置
├── quartz.layout.ts        # 页面布局
├── package.json            # 命令和依赖
└── public/                 # 构建产物,不手动编辑

不同 Quartz 项目可能把内容目录命名为 content、notes 或其他名称。本项目使用的是 phereblog,操作时以自己的项目配置和 package.json 为准。

最稳妥的做法,是只让 Obsidian 打开内容目录,而不是打开整个 Git 项目。也可以在 Vault 中创建一个软链接作为入口:

ln -s "$HOME/Projects/my-blog/content" \
  "$HOME/Documents/Obsidian/blog"

这里的两个路径都是示例:

  • 第一个路径是真实的博客内容目录。
  • 第二个路径是 Obsidian Vault 中看到的入口。

软链接不是复制文件,Obsidian 中修改的仍然是项目里的真实 Markdown。软链接只解决访问问题,不会自动提交,也不会自动发布。如果想确认它指向哪里,可以运行:

readlink "$HOME/Documents/Obsidian/blog"

项目根目录的 .gitignore 应该忽略以下内容:

  • node_modules
  • public
  • .obsidian
  • 构建缓存
  • 本地环境变量文件
  • 不准备公开的草稿或模板

提交前一定要检查,私人笔记、工作资料、API Key、密码和 Token 都不能进入公开仓库。

四、写文章、管理图片和本地预览

1. 创建文章

在内容目录的 posts/ 下创建 Markdown 文件,例如 hello-world.md:

---
title: 我的第一篇文章
date: 2026-08-08
description: 用一句话介绍这篇文章。
tags:
  - 随笔
draft: false
---
# 我的第一篇文章
 
从这里开始写正文。

文章开头的 YAML 区域叫 frontmatter:

  • title:文章标题
  • date:发布日期
  • description:文章摘要
  • tags:文章标签
  • draft:是否为草稿

文章还没有写完时,可以设置:

draft: true

Quartz 构建时会过滤 draft 文章,因此它不会进入正式网站。完成后改为 false,再提交发布。

2. 管理图片

推荐在文章目录下使用 assets 文件夹:

content/posts/assets/

在 Obsidian 设置中,可以把附件位置设置为“当前文件夹下的子文件夹”,子文件夹名称填写 assets。这样粘贴图片时,图片会自动放到文章附近。

Markdown 引用:

![图片说明](assets/example.png)

Obsidian 嵌入:

![[assets/example.png]]

图片必须位于博客内容目录中,才能被 Git 提交并由 Quartz 构建。不要把图片直接放进 public/,因为 public/ 是每次构建自动生成的目录。

一个图片的完整路径变化大致是:

content/posts/assets/example.png
    ↓ npm run build
public/posts/assets/example.png
    ↓ Cloudflare Pages
https://blog.example.com/posts/assets/example.png

文件名尽量使用简单的中文、英文或数字,注意大小写完全一致。较大的图片可以先压缩成 WebP、JPG 或 PNG。

3. 本地预览

在项目根目录运行:

npm run dev

然后打开:

http://localhost:8080

修改文章后,开发服务器一般会自动重新构建。发布前重点检查:

  • 标题、日期、标签是否正确
  • 图片和双链是否可用
  • 手机尺寸下是否正常
  • 草稿是否没有出现在正式内容中
  • 首页和文章目录是否正常

正式构建可以运行:

npm run build

成功后会生成 public/ 目录,这个目录不需要提交到 GitHub。

五、配置 Cloudflare Pages 自动部署

1. 创建 Pages 项目

进入 Cloudflare 控制台的 Workers & Pages,创建 Pages 项目并选择连接 GitHub。

首次连接时,Cloudflare 会请求 GitHub 授权。建议只授权它访问博客仓库,不要开放整个账号的所有仓库。

按照当前 Quartz 项目填写构建配置:

配置项填写内容
Git providerGitHub
Repository你的博客仓库
Production branchmain
Root directory/
Build commandnpm run build
Build output directorypublic
Node.js version22

Root directory 必须是包含 package.json、quartz.config.ts 和内容目录的项目根目录。不能填成 posts/,因为构建命令需要从项目根目录执行。

如果 Cloudflare 没有自动识别 Node.js 版本,可以在 Settings → Environment variables 中设置:

NODE_VERSION=22

保存并部署后,Cloudflare 会安装依赖、运行 npm run build,并把 public/ 中的文件发布出去。

2. 自动部署是怎么触发的

Cloudflare Pages 连接 GitHub 后,会监听仓库的提交:

本地修改
    ↓ git commit
推送到 GitHub

Cloudflare Pages 检测到 push

运行 npm run build

上传 public/

网站更新

因此,“推送到 GitHub 后自动发布”需要几个前提:

  1. Cloudflare Pages 连接的是正确的仓库。
  2. main 被设置为生产分支。
  3. 自动部署没有被暂停。
  4. 构建命令和输出目录正确。
  5. 本次构建成功。

推送到其他分支时,通常会生成预览部署,不会直接覆盖正式网站。

3. 绑定自定义域名

部署成功后,在 Pages 项目的 Custom domains 中添加域名,例如:

blog.example.com

如果 DNS 由 Cloudflare 管理,通常可以直接按照控制台提示完成配置。如果 DNS 在其他服务商,则需要按照 Pages 给出的目标地址创建 CNAME 记录。

刚绑定域名时,如果出现 DNS 错误,先检查 DNS 记录和 Pages 项目绑定关系,并等待 DNS 传播。没有自定义域名时,也可以直接使用:

你的项目名.pages.dev

六、日常发布:从写完文章到上线

以后每次发布都可以遵循同一条流程:

  1. 在 Obsidian 中写文章。
  2. 设置 frontmatter,未完成的文章保持 draft: true。
  3. 运行 npm run dev 检查本地效果。
  4. 运行 npm run build 确认正式构建成功。
  5. 使用 Git 提交并推送。
  6. 在 Cloudflare Pages 查看部署结果。

最基本的 Git 发布命令是:

git add content
git commit -m "发布新文章"
git push origin HEAD:main

如果你的内容目录叫 phereblog,就把 content 替换成 phereblog。

为了减少重复输入,也可以在终端配置两个快捷命令:

viewblog

用于进入项目并启动 npm run dev。

pubblog

用于添加内容、提交并推送到 GitHub。

快捷命令通常写在 ~/.zshrc 或 ~/.bashrc 中。配置后,新开终端,或者运行:

source ~/.zshrc

发布命令会直接推送到生产分支,所以最好形成“先预览、再构建、最后发布”的习惯。

七、常见问题和检查顺序

文章没有出现在网站

按这个顺序检查:

  1. 文件是否放在 Quartz 配置指定的内容目录。
  2. frontmatter 是否有 YAML 格式错误。
  3. 是否设置了 draft: true。
  4. 是否执行了 git add、git commit 和 git push。
  5. Cloudflare Pages 最新部署是否成功。

图片线上无法显示

检查三件事:

  1. 图片是否放在内容目录中。
  2. 引用路径是否相对于当前文章正确。
  3. 文件名大小写是否完全一致。

本地构建后,可以确认 public/ 下是否生成了对应图片。

git push 没有权限

先检查远程地址:

git remote -v

再测试 SSH:

ssh -T git@github.com

如果仓库属于组织,还需要确认 GitHub 账号有写入权限。

Cloudflare 构建失败

先在本地运行:

npm install
npm run build

再检查 Cloudflare 的 Node.js 版本、Root directory、Build command 和 Output directory。大多数 Pages 构建问题都可以从部署日志中找到具体原因。

最后检查清单

第一次搭建完成后,确认以下事项:

  • GitHub 账号已注册并完成邮箱验证
  • Cloudflare 账号已注册
  • Obsidian、Git、Node.js 已安装
  • GitHub 仓库已经创建
  • Git SSH 或 HTTPS 认证已经配置
  • 公开文章放在内容目录中
  • 私人笔记和密钥没有进入仓库
  • 本地 npm run build 成功
  • Cloudflare Pages 已连接 GitHub
  • Production branch 是 main
  • Build command 是 npm run build
  • Output directory 是 public
  • 已经先本地预览,再推送发布

搭建个人博客不需要一次完成所有功能。先让“写文章、看效果、提交、部署”这条链路稳定运行,之后再逐步增加自定义域名、图片、样式和自动化命令。真正重要的是,文章内容始终掌握在自己手里。

合规提醒

  • 本教程适用于个人博客、作品集、技术文档等网站。
  • 如果运营商业网站或提供互联网信息服务,请根据业务场景了解并遵守所在地相关法律法规和监管要求。