Maker Jackie
博客

我是怎么开发和部署这个博客网站的

从仓库结构、内容工作流到 GitHub Actions + Cloudflare Workers 部署,我是怎么把 Maker Jackie 这个博客跑起来的。

先说结论:我没有给这个博客上复杂的 CMS,也没有拆成一堆服务。我选的是一条更适合自己长期更新的最短路径:

Next.js 16 + Fumadocs + MDX + GitHub Actions + Cloudflare Workers

这样做的结果是:

  • 写内容时,我更像是在维护一个文档仓库
  • 开发页面时,我还是在写一个普通的 Next.js 项目
  • 发布时,我只需要 push 到 GitHub,线上就会自动更新

我真正想解决的,不是“做博客”,而是“持续输出”

我做这个网站的目标,不是把它做成一个功能很多的内容平台,而是让它变成一个我愿意长期维护的公开工作台。

对我来说,最重要的是三件事:

  • 内容要好写,最好直接用 MDX
  • 结构要清楚,文档和博客能放在一个仓库里
  • 部署要稳定,不能每次上线都重新走一遍后台

所以这个仓库从一开始就被我定义成一个 Docs First 的项目:
内容优先,代码服务内容展示,而不是反过来。

我为什么选这套技术

1. Next.js 16

我需要的不是一个“纯博客生成器”,而是一个以后还能继续扩展的站点。

Next.js 的好处是很明确的:

  • 文档、博客、首页都能放在同一个项目里
  • 以后如果我要加页面、表单、工具或者会员能力,不需要迁站
  • 本地开发体验成熟,生态也稳

2. Fumadocs

这个项目本质上是文档站优先,所以 Fumadocs 非常合适。

它帮我解决了这些问题:

  • 文档路由组织
  • 导航和目录
  • MDX 内容渲染
  • 文档站的基础体验

我只需要把内容放进 content/docs/,再维护好 meta.json,整个站点结构就能稳定运转。

3. Cloudflare Workers

我选 Cloudflare,不是因为“最炫”,而是因为它对我现在这个站点足够简单直接:

  • 全球访问速度不错
  • 自定义域名接入自然
  • @opennextjs/cloudflare 配合后,部署链路比较顺

对于一个以内容为主、页面为辅的站点,这个组合已经够用了。

4. GitHub Actions

我最后没有选“去平台后台点按钮发布”的方式,而是把发布逻辑写进仓库。

原因很简单:

  • 过程可见
  • 出问题容易排查
  • 回滚更直接
  • 以后我自己或者 AI 帮我维护,路径都一致

我平时怎么开发这个站

我的日常流程其实很朴素:

  1. content/docs/content/docs/blog/ 里写内容
  2. 如果是新文章,就补上对应的 meta.json
  3. 本地用 pnpm dev 预览
  4. 提交前跑一次 pnpm types:check
  5. push 到 GitHub

常用命令就是这几个:

pnpm install
pnpm dev
pnpm types:check
pnpm build
pnpm preview

这样做最大的好处是:内容和代码在一个地方,但内容优先级更高。

大多数时候,我并不需要改组件,只要改 MDX 就够了。

我是怎么把它部署到线上的

我现在的正式部署链路是:

本地开发 -> push 到 GitHub main -> GitHub Actions -> Cloudflare Workers

仓库里对应的几个关键文件分别负责不同的事:

  • wrangler.jsonc:定义 Worker 名称、域名路由和运行配置
  • open-next.config.ts:让 Next.js 走 Cloudflare 的部署适配
  • .github/workflows/deploy-cloudflare.yml:定义自动部署流程
  • package.json:定义 previewdeploy 这些脚本

工作流触发后,核心执行步骤就是:

pnpm install --frozen-lockfile
pnpm types:check
pnpm run deploy

也就是说,线上发布不是靠我手动去 Cloudflare 后台点部署,而是 GitHub Action 直接把当前代码发到 Cloudflare。

我踩过的几个真实坑

1. pnpm deploy 不等于 pnpm run deploy

这是这次最真实的坑。

pnpm 10 里,deploy 会优先被当成 workspace 子命令,所以:

pnpm deploy

不一定会执行你在 package.json 里写的脚本。

正确写法是:

pnpm run deploy

如果你在 GitHub Actions 里写错了,日志里就会看到类似 “A deploy is only possible from inside a workspace” 这样的报错。

2. 域名问题不一定是代码问题

我还遇到过一个很容易误判的问题:
站点本身已经部署成功了,但域名访问却跳到了别的地方。

这种情况,很多人第一反应是“是不是代码里写了跳转”,但真实原因往往在 Cloudflare 后台,比如:

  • Redirect Rules
  • Page Rules
  • Bulk Redirects
  • DNS 没完全切到 Cloudflare

所以只要你看到线上已经返回了 Cloudflare 的 Worker 页面,就先去查域名层和规则层,不要先在仓库里瞎改。

3. 部署成功,不代表域名一定绑定正确

wrangler.jsonc 里除了 Worker 名称,还定义了正式域名路由。

如果这里的 routes 和你实际想绑定的域名不一致,或者 Cloudflare 侧没有接好,自定义域名的访问结果就可能不符合预期。

这套方案为什么适合我

我现在最看重的不是“功能最多”,而是“维护成本最低,且能稳定输出”。

这套方案对我最有价值的地方是:

  • 写文章很轻,直接写 MDX
  • 结构很稳,博客和文档不用拆仓库
  • 部署很短,push 就能更新
  • 回滚很简单,直接回退 Git 提交再发一次

对一个正在持续探索内容、产品和公开工作流的人来说,这种形态比一个花哨但复杂的内容系统更适合长期使用。

如果你也想照着做

你可以先照这个最小清单来搭:

  1. Next.js 建站
  2. Fumadocs 管文档和 MDX
  3. 把正式内容统一放到 content/docs/
  4. 用 GitHub Actions 跑检查和部署
  5. Cloudflare Workers 托管线上版本

如果你只想先把“能持续发布”这件事跑通,这条路径已经足够好了。

最后

这个博客对我来说,不只是一个展示页,更像一个不断公开更新的工作台。

我希望它保持一个很重要的特征:内容能快速写出来,站点能稳定发出去,维护成本尽量低。

如果以后我再继续扩展它,大概率也是沿着这个原则往前走,而不是先把系统做复杂。

如果你想看更偏操作手册的版本,可以继续读:

目录