Cloudflare Worker + R2:让 AI 帮你部署后端

Cloudflare Worker + R2:让 AI 帮你部署后端
想搞个小工具——图床、短链、API 代理——但不想维护服务器。VPS 要续费、要装 Nginx、要配证书、要防 DDoS……太累了。
后来发现 Cloudflare Worker + R2 这套组合:代码扔上去就跑,存储按用量付费,免费额度够个人用,而且 CLI 操作简单到 AI 都能帮你部署。
现在我的图床、文章发布、API 网关全跑在上面,一年成本 $0。
这是什么
Worker:Cloudflare 的 Serverless 函数,类似 AWS Lambda,但:
- 冷启动快(< 5ms)
- 免费 10 万次/天
- 全球边缘节点,延迟低
- 支持自定义域名
R2:Cloudflare 的对象存储,兼容 S3 API,但:
- 免出口流量费(S3 最贵的就是这个)
- 免费 10 GB 存储 + 100 万次请求/月
- Worker 里直接绑定,不用配 SDK
Wrangler:Cloudflare 的 CLI 工具,本地开发、部署、管理全靠它。
效果展示
部署一个图床:
# 创建 R2 存储桶
wrangler r2 bucket create images
# 部署 Worker
wrangler deploy
# 上传图片测试
curl -X POST https://img.example.com/upload \
-H "Authorization: Bearer sk-xxx" \
-F "file=@screenshot.png"
# 返回:{"url": "https://img.example.com/abc123.png"}
从写代码到上线,10 分钟。
快速开始
1. 安装 Wrangler
# 推荐用 pnpm(也可以用 npm/bun)
pnpm add -g wrangler
# 验证安装
wrangler --version
2. 登录 Cloudflare
wrangler login
会打开浏览器授权,授权后本地就能操作你的 Cloudflare 账户了。
3. 创建第一个 Worker
mkdir my-api && cd my-api
wrangler init
选择 TypeScript,生成的项目结构:
my-api/
├── src/
│ └── index.ts # 入口文件
├── wrangler.toml # 配置文件
└── package.json
4. 写个 Hello World
src/index.ts:
export default {
async fetch(request: Request): Promise<Response> {
return new Response("Hello from Cloudflare Worker!");
},
};
5. 本地调试
wrangler dev
浏览器打开 http://localhost:8787,看到 Hello World。
6. 部署上线
wrangler deploy
返回一个 *.workers.dev 的 URL,直接能访问。
绑定 R2 存储
1. 创建 Bucket
wrangler r2 bucket create my-bucket
2. 配置绑定
wrangler.toml:
name = "my-api"
main = "src/index.ts"
compatibility_date = "2024-01-01"
<span class="private-link" title="未发布的笔记">r2_buckets</span>
binding = "BUCKET" # 代码里用这个名字访问
bucket_name = "my-bucket"
3. 代码里使用
interface Env {
BUCKET: R2Bucket; // 类型定义
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
if (request.method === "PUT") {
// 上传文件
const body = await request.arrayBuffer();
await env.BUCKET.put("hello.txt", body);
return new Response("Uploaded!");
}
if (request.method === "GET") {
// 下载文件
const object = await env.BUCKET.get("hello.txt");
if (!object) return new Response("Not found", { status: 404 });
return new Response(object.body);
}
return new Response("Method not allowed", { status: 405 });
},
};
R2 API 很简单:put()、get()、delete()、list(),够用了。
设置密钥(Secrets)
API Key 不要写死在代码里,用 Wrangler 管理:
# 设置密钥(交互式输入,不会显示在屏幕上)
<REDACTED_TOKEN>
# 查看已设置的密钥
wrangler secret list
代码里通过 env.API_KEY 访问:
interface Env {
BUCKET: R2Bucket;
API_KEY: string;
}
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const auth = request.headers.get("Authorization");
if (auth !== `Bearer ${env.API_KEY}`) {
return new Response("Unauthorized", { status: 401 });
}
// ...
},
};
绑定自定义域名
# 方法 1:在 wrangler.toml 里配置
# routes = [{ pattern = "api.example.com", custom_domain = true }]
# 方法 2:在 Cloudflare Dashboard 里配置
# Workers & Pages → 你的 Worker → Settings → Domains & Routes
前提:域名已经托管在 Cloudflare(DNS 由 CF 管理)。
常用命令速查
# === Worker ===
wrangler init # 初始化项目
wrangler dev # 本地开发
wrangler deploy # 部署
wrangler tail # 实时查看日志
wrangler delete # 删除 Worker
# === R2 ===
wrangler r2 bucket create <name> # 创建存储桶
wrangler r2 bucket list # 列出存储桶
wrangler r2 bucket delete <name> # 删除存储桶
wrangler r2 object put <bucket>/<key> --file=<path> # 上传文件
wrangler r2 object get <bucket>/<key> # 下载文件
wrangler r2 object delete <bucket>/<key> # 删除文件
# === Secrets ===
wrangler secret put <name> # 设置密钥
wrangler secret list # 列出密钥
wrangler secret delete <name> # 删除密钥
# === 调试 ===
wrangler whoami # 查看登录账户
wrangler login # 重新登录
我踩过的坑
1. wrangler dev 默认不绑定 R2
本地开发时访问 env.BUCKET 会报错。解决:
wrangler dev --remote
这样会用真实的 R2,但请求数会计入配额。
2. R2 的 body 是流,不能直接用两次
// 错误:body 只能读一次
const text1 = await object.text();
const text2 = await object.text(); // 报错!
// 正确:先读成 buffer
const buffer = await object.arrayBuffer();
3. 部署后改动没生效
Cloudflare 有缓存,刷新可能看到旧版本。两个办法:
- 等 1-2 分钟
- 强刷:
Cmd+Shift+R
实际案例
我现在跑着这些 Worker:
| 服务 | 用途 | R2 存储 |
|---|---|---|
s.chen.rs |
文章发布 | 文章 JSON + 索引 |
img.chen.rs |
图床 | 图片文件 |
ai.chen.rs |
OpenAI Key 轮询网关 | Key 配置 |
每个都是一个 Worker + 一个 R2 Bucket,代码不超过 500 行。
为什么 AI 能直接操作
Wrangler 是纯命令行工具,所有操作都可以非交互式完成:
# 创建项目
wrangler init my-project --yes
# 部署(不需要确认)
wrangler deploy
# 设置密钥(可以从 stdin 读取)
echo "sk-xxx" | <REDACTED_TOKEN>
这意味着你可以让 Claude Code 帮你:
- 写 Worker 代码
- 创建 R2 存储桶
- 部署上线
- 设置密钥
整个流程全自动。
下一步
- 加 KV:需要键值存储?
wrangler kv:namespace create <name> - 加 D1:需要 SQLite?
wrangler d1 create <name> - 加定时任务:在
wrangler.toml里配置[triggers]
附录:给 AI 的复现指令
帮我用 Cloudflare Worker + R2 搭建一个简单的图床服务。
目标:POST 上传图片,返回公开 URL;GET 访问图片。
技术栈:TypeScript + Wrangler
项目结构:
img-worker/
├── src/index.ts # 主入口
├── wrangler.toml # 配置
└── package.json
wrangler.toml 配置:
name = "img-worker"
main = "src/index.ts"
compatibility_date = "2024-01-01"
<span class="private-link" title="未发布的笔记">r2_buckets</span>
binding = "BUCKET"
bucket_name = "images"
核心逻辑:
1. POST /upload:验证 Authorization header,读取文件,生成哈希作为文件名,存入 R2,返回 URL
2. GET /:key:从 R2 读取文件,设置正确的 Content-Type,返回
环境变量:
- API_KEY: 上传认证密钥(通过 <REDACTED_TOKEN> 设置)
部署命令:
wrangler r2 bucket create images
<REDACTED_TOKEN>
wrangler deploy
成功标志:
1. curl POST 上传图片返回 URL
2. 浏览器访问 URL 能看到图片
附录:定价
| 服务 | 免费额度 | 超出后 |
|---|---|---|
| Worker 请求 | 10 万/天 | $0.50/百万 |
| R2 存储 | 10 GB | $0.015/GB/月 |
| R2 A 类操作 | 100 万/月 | $4.50/百万 |
| R2 B 类操作 | 1000 万/月 | $0.36/百万 |
| R2 出口流量 | 无限 | $0 |
个人项目基本用不完免费额度。