更新后部署失败?请查看 CHANGELOG 了解 Breaking Changes。
注意:本项目专为 Cloudflare Workers 生态设计,深度集成 D1、R2、KV、Workflows 等服务,仅支持部署在 Cloudflare Workers。
基于 Cloudflare Workers 的现代化全栈博客 CMS。
- 文章管理 — 富文本编辑器,支持代码高亮、图片上传、草稿/发布流程
- 标签系统 — 灵活的文章分类
- 评论系统 — 支持嵌套回复、邮件通知、审核机制
- 友情链接 — 用户申请、管理员审核、邮件通知
- 全文搜索 — 基于 Orama 的高性能搜索
- 媒体库 — R2 对象存储,图片管理与优化
- 用户认证 — GitHub OAuth 登录,权限控制
- 数据统计 — Umami 集成,访问分析与热门文章
- AI 辅助 — Cloudflare Workers AI 集成
| 服务 | 用途 |
|---|---|
| Workers | 边缘计算与托管 |
| D1 | SQLite 数据库 |
| R2 | 对象存储(媒体文件) |
| KV | 缓存层 |
| Durable Objects | 分布式限流 |
| Workflows | 异步任务(内容审核、定时发布) |
| Queues | 消息队列(邮件通知) |
| Workers AI | AI 能力 |
| Images | 图片优化 |
- 框架:React 19 + TanStack Router/Query
- 样式:TailwindCSS 4
- 表单:React Hook Form + Zod
- 图表:Recharts
- 网关层:Hono(认证路由、媒体服务、缓存控制)
- 业务层:TanStack Start(SSR、Server Functions)
- 数据库:Drizzle ORM + drizzle-zod
- 认证:Better Auth(GitHub OAuth)
TipTap 富文本 + Shiki 代码高亮
src/
├── features/
│ ├── posts/ # 文章管理(其他模块结构类似)
│ │ ├── api/ # Server Functions(对外接口)
│ │ ├── data/ # 数据访问层(Drizzle 查询)
│ │ ├── posts.service.ts # 业务逻辑
│ │ ├── posts.schema.ts # Zod Schema + 缓存 Key 工厂
│ │ ├── components/ # 功能专属组件
│ │ ├── queries/ # TanStack Query Hooks
│ │ └── workflows/ # Cloudflare Workflows
│ ├── comments/ # 评论、嵌套回复、审核
│ ├── tags/ # 标签管理
│ ├── media/ # 媒体上传、R2 存储
│ ├── search/ # Orama 全文搜索
│ ├── auth/ # 认证、权限控制
│ ├── dashboard/ # 管理后台数据统计
│ ├── email/ # 邮件通知(Resend)
│ ├── cache/ # KV 缓存服务
│ ├── config/ # 博客配置
│ ├── friend-links/# 友情链接(申请、审核)
│ └── ai/ # Workers AI 集成
├── routes/
│ ├── _public/ # 公开页面(首页、文章列表/详情、搜索)
│ ├── _auth/ # 登录/注册相关页面
│ ├── _user/ # 用户相关页面
│ ├── admin/ # 管理后台(文章、评论、媒体、标签、设置)
│ ├── rss[.]xml.ts # RSS Feed
│ ├── sitemap[.]xml.ts # Sitemap
│ └── robots[.]txt.ts # Robots.txt
├── components/ # UI 组件(ui/, common/, layout/, tiptap-editor/)
├── lib/ # 基础设施(db/, auth/, hono/, middlewares)
└── hooks/ # 自定义 Hooks
请求 → Cloudflare CDN(边缘缓存)
↓ 未命中
server.ts(Hono 入口)
├── /api/auth/* → Better Auth
├── /images/* → R2 媒体服务
└── 其他 → TanStack Start
↓
中间件注入(db, auth, session)
↓
路由匹配 + Loader 执行
↓
KV 缓存 ←→ Service 层 ←→ D1 数据库
↓
SSR 渲染(带缓存头)
请参考 Flare Stack Blog 部署教程,包含 Cloudflare 资源创建、凭证获取、GitHub OAuth 配置、两种部署方式的详细图文步骤及常见问题排查。
| 文件 | 用途 |
|---|---|
.env |
客户端变量(VITE_*),Vite 读取 |
.dev.vars |
服务端变量,Wrangler 注入 Worker env |
| 变量名 | 用途 | 说明 |
|---|---|---|
CLOUDFLARE_API_TOKEN |
CI/CD | Cloudflare API Token(Worker 部署 + D1 读写权限) |
CLOUDFLARE_ACCOUNT_ID |
CI/CD | Cloudflare Account ID |
D1_DATABASE_ID |
CI/CD | D1 数据库 ID |
KV_NAMESPACE_ID |
CI/CD | KV 命名空间 ID |
BUCKET_NAME |
CI/CD | R2 存储桶名称 |
BETTER_AUTH_SECRET |
运行时 | 会话加密密钥,运行 openssl rand -hex 32 生成 |
BETTER_AUTH_URL |
运行时 | 应用 URL(如 https://blog.example.com) |
ADMIN_EMAIL |
运行时 | 管理员邮箱 |
GITHUB_CLIENT_ID |
运行时 | GitHub OAuth Client ID |
GITHUB_CLIENT_SECRET |
运行时 | GitHub OAuth Client Secret |
CLOUDFLARE_ZONE_ID |
运行时 | Cloudflare Zone ID |
CLOUDFLARE_PURGE_API_TOKEN |
运行时 | 具有 Purge CDN 权限的 API Token |
DOMAIN |
运行时 | 博客域名(如 blog.example.com) |
| 变量名 | 用途 | 说明 |
|---|---|---|
TURNSTILE_SECRET_KEY |
运行时 | Cloudflare Turnstile 人机验证 Secret Key |
VITE_TURNSTILE_SITE_KEY |
构建时 | Cloudflare Turnstile Site Key |
UMAMI_SRC |
运行时 | Umami 基础 URL(Cloud: https://cloud.umami.is) |
UMAMI_API_KEY |
运行时 | Umami Cloud API key(仅 Cloud 版本) |
UMAMI_USERNAME |
运行时 | Umami 用户名(仅自部署版本) |
UMAMI_PASSWORD |
运行时 | Umami 密码(仅自部署版本) |
VITE_UMAMI_WEBSITE_ID |
构建时 | Umami Website ID |
VITE_BLOG_TITLE |
构建时 | 博客标题 |
VITE_BLOG_NAME |
构建时 | 博客短名称 |
VITE_BLOG_AUTHOR |
构建时 | 作者名称 |
VITE_BLOG_DESCRIPTION |
构建时 | 博客描述 |
VITE_BLOG_GITHUB |
构建时 | GitHub 主页链接 |
VITE_BLOG_EMAIL |
构建时 | 联系邮箱 |
- Bun >= 1.3
- Cloudflare 账号(用于远程 D1/R2/KV 资源)
# 安装依赖
bun install
# 配置环境变量
cp .env.example .env # 客户端变量
cp .dev.vars.example .dev.vars # 服务端变量
# 配置 Wrangler
cp wrangler.example.jsonc wrangler.jsonc
# 编辑 wrangler.jsonc,填入你的资源 ID
# 启动开发服务器
bun dev| 命令 | 说明 |
|---|---|
bun dev |
启动开发服务器(端口 3000) |
bun run build |
构建生产版本 |
bun run test |
运行测试 |
bun lint |
ESLint 检查 |
bun check |
类型检查 + Lint + 格式化 |
| 命令 | 说明 |
|---|---|
bun db:studio |
启动 Drizzle Studio(可视化数据库) |
bun db:generate |
生成迁移文件 |
bun db:migrate |
应用迁移到远程 D1 |
默认配置使用远程 D1/R2/KV 资源。如需完全本地开发,可在 wrangler.jsonc 中移除 remote: true,Miniflare 会自动模拟这些服务:
注意:本地模拟的数据不会同步到远程,适合初期开发和测试。本地数据库迁移使用:
wrangler d1 migrations apply DB


{ "d1_databases": [{ "binding": "DB", ... }], // 移除 "remote": true "r2_buckets": [{ "binding": "R2", ... }], // 移除 "remote": true "kv_namespaces": [{ "binding": "KV", ... }] // 移除 "remote": true }