由于对国内云厂商的厌恶提升,且为了blog服务性能提升,这里将博客静态资源从腾讯云迁移到 Cloudflare R2,其实步骤还是挺繁琐的,包括 rclone 配置、Worker 部署和自定义域名绑定。但得益于AI协助,整个迁移过程大概 1 小时,0.5G 静态资源零停机切换完成。这里大概记录下完整步骤,供大家参考。
背景与目标
将静态资源从腾讯云迁移到 Cloudflare R2 主要有两个目的:
- 降低成本:Cloudflare R2 出口流量完全免费,后期计划废弃服务依赖国内云,实在是从登录到使用充满了流氓气息。
- 提升性能:利用 Cloudflare 全球 CDN 加速,优化博客访问速度和 SEO
最终架构
服务器本地目录
/var/www/blog/static-assets
↓ (rclone sync)
Cloudflare R2 (private bucket)
↓ (Worker)
static.1991421.cn (自定义域名)
架构特点:
- 博客 URL 不变
- R2 Bucket 保持私有
- 通过 Worker 提供访问
- 零出口流量费用
一、安装 rclone
在服务器上安装 rclone:
curl https://rclone.org/install.sh | sudo bash
二、配置 rclone 连接 R2
1. 启动配置向导
rclone config
2. 创建新的 remote
按照以下步骤配置:
- 选择
n新建 remote - 名称输入:
cf-r2 - 存储类型选择:
s3(S3 兼容对象存储) - Provider 选择:
47(Any other S3 compatible provider)
为什么不选 Cloudflare R2 选项? R2 不在内置厂商列表中,必须使用通用 S3 兼容配置。
3. 填写认证信息
在 Cloudflare R2 控制台创建 API 令牌后,你会看到三个字段,这里列下字段对应关系:
| Cloudflare 页面字段 | rclone 配置项 | 是否使用 |
|---|---|---|
| 访问密钥 ID | access_key_id | ✅ 必填 |
| 机密访问密钥 | secret_access_key | ✅ 必填 |
| 令牌值 | - | ❌ 忽略 |
在 rclone 中输入:
access_key_id> [你的访问密钥 ID]
secret_access_key> [你的机密访问密钥]
4. 配置连接参数
Region(留空):
region> [直接回车]
R2 没有 region 概念,留空是官方推荐做法。
Endpoint(必填):
endpoint> https://<AccountID>.r2.cloudflarestorage.com
示例:https://xxxxx.r2.cloudflarestorage.com
你可以在 R2 控制台的 Bucket 详情页找到这个地址。
Location Constraint(留空):
location_constraint> [直接回车]
ACL(留空 = private):
acl> [直接回车]
R2 不使用 S3 ACL,权限交给 Worker 管理。
Advanced config(不需要):
Edit advanced config? n
5. 确认配置
y) Yes this is OK
配置完成!
三、执行数据迁移
首次迁移(推荐使用 copy)
rclone copy /var/www/blog/static-assets cf-r2:static-assets \
--progress \
--transfers=16 \
--checkers=16
copy 命令只复制文件,不会删除目标端的文件,更安全。
日常同步(使用 sync)
rclone sync /var/www/blog/static-assets cf-r2:static-assets \
--progress \
--transfers=16 \
--checkers=16
sync 会让目标端与源端完全一致,会删除目标端多余的文件。
参数说明:
--progress:显示传输进度--transfers=16:并发传输 16 个文件--checkers=16:并发检查 16 个文件
四、配置 Cloudflare R2 Bucket
在 Cloudflare 控制台创建 R2 Bucket:
- Bucket 名称:
static-assets - 存储类型:标准
- 区域:自动(Auto)
- 公开访问:❌ 关闭(保持私有)
重要:不要开启公开访问,我们通过 Worker 来控制访问权限。
五、部署 Cloudflare Worker
1. 创建 Worker
在 Cloudflare 控制台:
- 进入 Workers & Pages
- 点击 创建应用程序
- 选择 创建 Worker
- 选择 从 Hello World 开始
2. 编写 Worker 代码
将以下代码粘贴到 Worker 编辑器:
export default {
async fetch(request, env) {
const url = new URL(request.url);
const key = url.pathname.slice(1);
if (!key) {
return new Response('Not Found', { status: 404 });
}
const object = await env.STATIC_ASSETS.get(key);
if (!object) {
return new Response('Not Found', { status: 404 });
}
return new Response(object.body, {
headers: {
'Content-Type':
object.httpMetadata?.contentType || 'application/octet-stream',
'Cache-Control': 'public, max-age=31536000, immutable'
}
});
}
};
代码说明:
- 从 URL 路径提取文件键名
- 从 R2 获取对象
- 设置正确的 Content-Type
- 添加长期缓存头(1 年)
3. 绑定 R2 Bucket
这是最关键的一步,很容易遗漏!
在 Worker 设置中:
- 进入 设置 > 变量和机密信息
- 选择 R2 存储桶绑定(不是环境变量!)
- 添加绑定:
- 变量名:
STATIC_ASSETS - R2 Bucket:选择
static-assets
- 变量名:
注意:必须使用 R2 Bucket 绑定,不能用环境变量或纯文本。

4. 测试 Worker
部署后,使用 workers.dev 域名测试:
curl -I https://static-assets.你的账号.workers.dev/2018-06-06-Validate.jpg
能正常返回图片说明 Worker 到 R2 的链路已打通。
六、绑定自定义域名
1. 添加自定义域名
在 Worker 设置中:
- 进入 触发器
- 点击 添加自定义域
- 输入域名:
static.1991421.cn
如果域名已在 Cloudflare 托管:
- DNS 记录会自动创建
- HTTPS 会自动启用
- 通常在 1 分钟内生效
2. 验证域名
curl -I https://static.1991421.cn/2018-06-06-Validate.jpg
检查响应头:
server: cloudflare
cache-control: public, max-age=31536000, immutable
看到这些说明已经正式上线!
七、更新博客引用
如果使用了新的域名,需要更新博客中的静态资源 URL,当然我这里保持不变,所以不需要这一步。如果需要更新,可以批量替换:
旧:https://old-domain.com/image.jpg
新:https://static.1991421.cn/image.jpg
可以使用批量替换工具完成。
总结
通过这次迁移实现了:
✅ 成本优化:R2 出口流量 $0
✅ 性能提升:Cloudflare 全球 CDN 加速
✅ 架构优化:Private Bucket + Worker 的标准实践
✅ 零停机迁移:URL 保持不变,用户无感知
整个迁移过程仅耗时 1 小时,0.5G 静态资源全部迁移完成。这是 Cloudflare R2 + Worker 做法。


