Skip to content
ratio's blog
Go back

博客搭建记:从 7 框架对比到一键发布

Draft
Draft

TL;DR:搭个人博客,调研了 7 个框架,最终选 Astro + Cloudflare Tunnel + Docker 双环境部署,配合 Telegram Bot 审批流,写草稿→点按钮→5 分钟自动上线。本文记录完整的决策过程和踩过的坑。


为什么要自己搭

我已经有一个 Obsidian 知识库(brain vault)和 x.com 账号,但缺少一个「我的地盘」——能写长文、不受平台限制、完全控制命运的个人网站。

几个约束决定了架构方向:

  1. 服务器是 Mac Mini,放在家里,没有公网 IP
  2. 不需要买 VPS,零运维开销是底线
  3. Agent 友好,以后 Archie 能直接帮我写文章、发文章
  4. 速度不能慢,国内虽然不用看了,但海外访问要快

翻译成人话:得用 Cloudflare 隧道 + 静态网站 + Agent 自动化。


选型:7 个框架,一个答案

没急着搭,先拉了个 Excel。7 个框架,每个写了个 hello world 感受手感:

框架语言构建速度生态模板体验综合评价
HugoGo⚡ 10ms⭐⭐⭐⭐⭐Go template 语法丑,if else 套三层想死快但折磨
AstroJS🟡 200ms⭐⭐⭐⭐写 JSX/TSX/HTML 都行,灵活生态好,MCP
ZolaRust⚡ 5ms⭐⭐⭐Tera 模板简洁,但插件太少小而美但局限
11tyJS🟡 300ms⭐⭐⭐模板自由度高,但文档不够好灵活但小众
JekyllRuby🐢 2s+⭐⭐Liquid 模板还行老了,Gem 麻烦
HexoJS🟡 500ms⭐⭐EJS 很普通Node 老牌,不再活跃
VitePressJS🟡 200ms⭐⭐⭐⭐Vue 生态,文档站首选做文档好,做博客一般

最终选了 Astro。决定性因素是两个:

  1. JS 生态 + MCP Server:Agent 开发是我现在的主方向,Astro 官方提供 MCP Server,模型可以直接查最新文档写代码。以后让 Archie 改主题、加组件、写文章,不需要培训一个新框架。

  2. Islands 架构:默认零 JS,只有需要交互的部分才加载。对内容驱动的博客来说是天然优势——访问者看到的 99% 都是纯 HTML,加载速度取决于 CDN,不取决于框架。

Zola 很想选——Rust 写的,快且干净,Tera 模板也写得舒服。但生态实在是太小了,GitHub 上 200 多个主题,大部分是 3 年前的。做博客没问题,做 Agent 自动化就捉襟见肘了。


主题:Astro Paper

选了 astro-paper,Astro 生态里最流行的博客主题(4.8K stars),Bear Blog 风格,极简。

装上之后踩了三个坑:

坑 1:Vite v8 + Tailwind v4

主题依赖 vite-tsconfig-paths 在 Vite v8 上 crash。锁到 Vite v7.3.3 解决。

教训:JS 生态更新快不是好事。稳定 > 新功能。

坑 2:Google Fonts

主题默认引用了 Google Fonts CSS,国内直接超时。删掉就好了,用系统字体 stack:system-ui, -apple-system, sans-serif,反而更快。

坑 3:OG Image 生成

自带的 OG 图片生成依赖 satori,需要加载字体文件。关掉,用 <meta og:image> 静态指定就行了。少一个依赖少一个坑。


部署架构

Cloudflare CDN (橙色云)

    │ HTTPS, 缓存, DDoS

    └── Cloudflare Tunnel (cloudflared)

            │ 加密通道

            └── Mac Mini (localhost)

                    ├── nginx :28080 → blog.ratio-dd.com
                    ├── nginx :28083 → blog-dev.ratio-dd.com (预览)
                    └── Docker 容器隔离

为什么不直接暴露服务器

我家是 CGNAT,Mac Mini 没有公网 IP。两个选择:

选 CF Tunnel。唯一代价是被 Cloudflare 绑定——但从第一天就用了 CF 的 DNS 和 CDN,没多绑。

nginx 做什么

Docker 隔离

Prod 和 dev 是两个独立的 Docker 容器,分别挂载 dist/dist-draft/

好处:

缓存策略

两层缓存:

  1. nginx 层 Cache-Control: max-age=86400(静态资源 24h)
  2. Cloudflare Cache Rule:对整个 blog.ratio-dd.com/* 开启 CDN 缓存

发新文章后跑 purge-cache.sh 清掉 CF 缓存,保证用户看到最新内容。CF 缓存 HIT 时响应 ~280ms,全球 CDN 分发。


审批发布流:Archie 搞定一切

传统流程:写 MD → git push → CI/CD → 等构建 → 网站更新。

我懒。Archie 帮我去掉了所有手动步骤:

我:写草稿 (draft: true)

Archie:npm run build:draft → 推预览站 → 发 Telegram 消息

我:看到预览链接 + 文章信息,点 ✅ 发布 或 ❌ 取消

Archie:收 callback → 5 分钟倒计时 → npm run build → purge cache → pin 消息

关键设计

编译时强制审批approval-gate.mjsnpm run build 之前检查 .approved-posts 文件。没审批的文章即使 draft: true 也会被拦住。

三重防护:

  1. draft: true → 预览站可见,线上不可见
  2. approval-gate.mjs → build 前检查,未审批的不让过
  3. Telegram 审批 → 只有我点 ✅ 才会写入 .approved-posts

预览站隔离blog-dev.ratio-dd.com 独立 Docker 容器 + Basic Auth。预览站和正式站物理隔离,草稿绝不可能泄露到生产。

消息实时更新:同样的 Telegram 消息,从”预览待审批”→“已批准 倒计时”→“已取消”→”✅ 已发布”,整个生命周期的状态变化都在一条消息里呈现。


总结:哪些对了,哪些还会改

做对了的

还没做的


Share this post:

Previous Post
博客发布 Harness:一个 Agent 和人的协作实验
Next Post
Hello Astro