banner
约 2,100 字
7 分钟

Rin 博客部署教程:Cloudflare 全家桶零服务器搭站

Rin 博客部署教程:Cloudflare 全家桶零服务器搭站

摘要

Rin 是全 Cloudflare 栈的博客系统(Pages + Workers + D1 + R2)。含一键部署、Fork+Actions 配置清单、GitHub 登录与自定义域名对接。

Rin 博客部署教程:Cloudflare 全家桶零服务器搭站

想写博客又不想买服务器、不想备案、不想每个月交主机费。Rin 的做法是把整套博客拆成 Cloudflare 的四个服务——前端 Pages、后端 Workers、数据库 D1、图床 R2——全部落在免费额度里。

仓库:openRin/Rin。本文的截图就是一套跑在 Rin 上的真实站点首页。

跑在 Rin 上的博客首页实拍:文章列表、标签、归档与搜索
跑在 Rin 上的博客首页实拍:文章列表、标签、归档与搜索

一句坦白:本站现在用的是 flare-stack-blog,但 Rin 是同一个路数的方案(纯 Cloudflare 生态),作为入门依然很合适——它把「写作即发布」这件事做得更彻底。

一、Rin 是什么,适合谁

架构上它是前后端分离的 Serverless 博客:

部件

承载

作用

前端

Cloudflare Pages

静态页面,全球 CDN 分发

后端

Cloudflare Workers

API、鉴权、写文章

数据

Cloudflare D1

SQLite 数据库,存配置与文章

存储

Cloudflare R2

图片等静态资源

适合这几类人:

  • 不想维护服务器、反感运维

  • 追求打开速度的个人博主

  • 愿意折腾一次、之后只想安静写字的开发者

几个需要提前接受的点:

  • 功能仍在演进:多用户、组织类能力不是它的目标场景

  • 迁移只对 WordPress 友好,Hexo / Typecho 的文章要自己处理

  • R2 需要绑定支付方式(无用量不扣费,仅做身份验证;不绑就用不了图床)

二、准备清单

项目

说明

Cloudflare 账号

域名需要托管在 Cloudflare

GitHub 账号

用于 Fork 仓库、跑 Actions、配 OAuth 登录

Bun

本地开发与构建工具(官方脚本基于 Bun)

域名

建议前端 blog.你的域名、后端 api.你的域名 分开

Cloudflare API Token

至少含 Workers Scripts / D1 / R2 的编辑权限

Cloudflare Account ID

Dashboard 域名概览页右侧可见

三、路线选择:三条路,选一条

路线

适合

特点

一键部署命令

想最快看到成果

本地一条命令建库、建桶、部署前后端

Fork + GitHub Actions

长期维护、跟着上游更新

push 即部署,配置一次永久受益

手动 Pages + Actions

想精确控制每个环节

步骤多,但每一步都可控

第三种的本质是「把第二条路的自动化拆开手工做一遍」,日常没人这么干。下面重点讲前两条。

四、路线 A:一条命令部署

本地需要 Node 与 Bun 环境,然后:

bash
git clone https://github.com/openRin/Rin.git && cd Rin
bun install
cp .env.example .env.local     # 按注释填自己的配置
bun run dev                    # 本地预览:http://localhost:5173

本地跑通后,配置两个环境变量再一键部署:

bash
export CLOUDFLARE_API_TOKEN="你的 API Token"
export CLOUDFLARE_ACCOUNT_ID="你的 Account ID"

bun run deploy          # 前端 + 后端一起部署
bun run deploy:server   # 只部署后端
bun run deploy:client   # 只部署前端

部署脚本会自动完成这些事:D1 数据库不存在就创建 → 从 R2_BUCKET_NAME 推导 S3_* 存储配置 → 部署后端到 Workers → 构建并部署前端到 Pages → 执行数据库迁移。

可选的资源名覆盖(不设则用默认值):

变量

默认

说明

WORKER_NAME

rin-server

后端 Worker 名

PAGES_NAME

rin-client

前端 Pages 项目名

DB_NAME

rin

D1 数据库名

R2_BUCKET_NAME

不设就不会自动选桶,要用图床必须设

五、路线 B:Fork + GitHub Actions

想长期跟上游更新,用这条。核心是「Fork 一次,之后只同步」。

1. Fork 并开启 Actions

Fork openRin/Rin,进入你仓库的 Actions 页,点击启用工作流。

2. 配置 Secrets(必填)

仓库 → Settings → Secrets and variables → Actions → Secrets

Secret

说明

CLOUDFLARE_API_TOKEN

具备 Workers 与 Pages 权限的 API Token

CLOUDFLARE_ACCOUNT_ID

Cloudflare 账户 ID

3. 配置 Variables(可选)

同页面的 Variables 标签:

变量

作用

WORKER_NAME / PAGES_NAME / DB_NAME

自定义资源名

NAME / DESCRIPTION / AVATAR

站点名称、描述、头像

R2_BUCKET_NAME

指定复用的 R2 桶

4. 触发部署

  • push 到 main 自动构建部署

  • 或手动:Actions → Deploy → Run workflow

Rin 仓库自带几条工作流各司其职:ci.yml 跑类型与格式检查,test.yml 跑前后端测试,build.yml 构建并触发部署,deploy.yml 执行发布。检查失败不会发布,这点比手工部署省心。

5. 绑定后端域名

Cloudflare Dashboard → Workers & Pages → 找到 rin-server触发器

  1. 添加自定义域:api.你的域名

  2. 添加路由,把前端的订阅/SEO 请求转给后端:

  • https://blog.你的域名/sub/*

  • https://blog.你的域名/seo/*

6. 前端指向后端

到前端 Pages 项目的 设置 → 环境变量,把 API 地址改成后端域名:

bash
API_URL=https://api.你的域名

改完在部署记录里点一次重新部署即可生效。

六、图床:把 R2 接上

  1. Cloudflare → R2 → 新建存储桶(如 rin-storage

  2. 复制 S3 API 地址,只保留域名部分(如 https://abc123.r2.cloudflarestorage.com

  3. 给桶配一个公开访问域名(如 storage.你的域名),这才是图片真正对外访问的地址

  4. 到桶的管理 R2 API 令牌里创建令牌,权限选「管理员读和写」,立刻保存 Access Key ID 与 Secret Access Key(刷新后不再显示)

对应的环境变量/Secrets:

名称

S3_BUCKET

桶名,如 rin-storage

S3_REGION

auto

S3_ENDPOINT

R2 的 S3 API 域名(去掉路径)

S3_ACCESS_HOST

公开访问域名

S3_ACCESS_KEY_ID

R2 API 令牌的 Access Key ID

S3_SECRET_ACCESS_KEY

R2 API 令牌的 Secret Access Key

跨域报错时给桶加一条 CORS 策略,把 AllowedOrigins 换成你的前端域名:

JSON
[
  {
    "AllowedOrigins": ["https://blog.你的域名"],
    "AllowedMethods": ["GET", "DELETE", "HEAD", "POST", "PUT"],
    "AllowedHeaders": ["Content-Type"]
  }
]

七、用 GitHub 登录后台

Rin 靠 GitHub OAuth 做登录,到 GitHub OAuth Apps 新建应用:

字段

填什么

Homepage URL

前端域名,如 https://blog.你的域名

Authorization callback URL

后端域名 + 仓库文档规定的回调路径(形如 https://api.你的域名/user/github/callback,以官方文档为准)

创建后生成 client secret(需要账号开启二次验证),把这两个值配进仓库 Secrets:

Secret

来源

RIN_GITHUB_CLIENT_ID

OAuth App 的 Client ID

RIN_GITHUB_CLIENT_SECRET

OAuth App 的 Client Secret

JWT_SECRET

自己用密码生成器生成一串随机值

第一个用 GitHub 登录的人自动成为管理员,之后就能在后台写文章、改站点配置了。

八、验证清单

部署完按顺序过一遍,出问题最容易定位:

  1. 前端域名能打开,样式正常 → 说明 Pages 构建没问题

  2. 点 GitHub 登录能跳转并回来 → 说明 OAuth 回调地址与 API_URL 都对了

  3. 后台能保存文章 → 说明 Workers 与 D1 通了

  4. 上传一张图片并能在文章里显示 → 说明 R2 与 S3_* 配对了

九、常见问题排查

现象

可能原因

处理

Actions 跑红

Secrets 缺失或权限不足

核对 CLOUDFLARE_API_TOKEN 是否含 Workers/Pages 权限

前端能开但登录失败

API_URL 还指向旧地址

改前端环境变量后重新部署

图片传不上去

R2 未绑支付方式,或 S3_* 有拼写错误

先开通 R2,再逐项核对变量

图片显示不了

桶没配公开访问域名

给桶绑 storage.你的域名 并确认可匿名访问

文章列表空

D1 迁移没跑

重跑部署流程,或手动执行迁移

旧文章迁移

Rin 只对 WordPress 导入友好

Hexo/Typecho 需手工整理后再导入

数据备份建议直接导出 D1:Cloudflare 控制台 → D1 → 选库 → 导出。

写在最后

Rin 的价值在于把「博客」这件事的运维成本压到了零:没有服务器、没有备案、没有月账单,发布就是 git push。

不过要提醒一句——它的能力边界和你的需求要匹配。如果你只想要一个稳定的写作发布台,Rin 足够;如果你需要多作者、复杂评论体系或强 SEO 定制,本站换用的 flare-stack-blog 这类方案会更顺手。选型之前,先想清楚你未来一年会写多少字。

END