Cloudflare R2 提供兼容 S3 的 API,可以通过 Account ID、Access Key ID 和 Secret Access Key 连接到 Storage UI。
一、创建存储桶
- 在 Cloudflare 控制台打开 R2 Object Storage。
- 选择 Create bucket。
- 输入唯一的存储桶名称。
- 创建存储桶,并保留该名称用于 Storage UI 配置。
二、创建 API 凭据
打开 R2 Object Storage → Manage API tokens,然后创建 Account API token。
按实际需要选择最小权限:
- 需要完整文件管理时,选择 Object Read & Write。
- 只读连接使用 Object Read。
尽可能将 token 限制在目标存储桶范围内,创建后保存这些值:
- Access Key ID
- Secret Access Key
- Account ID
Secret Access Key 只会显示一次,请安全保存,不要通过 NEXT_PUBLIC_* 变量暴露。
当前控制台流程和权限选项以 Cloudflare R2 API token 文档 为准。
三、配置 Storage UI
本地开发时,将连接添加到 .env.local;部署时,将这些变量添加到部署平台的环境变量设置中:
STORAGE_1_PROVIDER=r2
STORAGE_1_NAME=Cloudflare R2
STORAGE_1_BUCKET=my-bucket
STORAGE_1_ACCOUNT_ID=your-cloudflare-account-id
STORAGE_1_ACCESS_KEY_ID=your-access-key-id
STORAGE_1_SECRET_ACCESS_KEY=your-secret-access-key
将 my-bucket 替换为 Cloudflare 中创建的真实存储桶名称。
Storage UI 始终根据 STORAGE_1_ACCOUNT_ID 生成 R2 endpoint(https://<account-id>.r2.cloudflarestorage.com),R2 没有自定义 endpoint 选项,因此 STORAGE_1_ENDPOINT 会被忽略,请仔细检查 Account ID:缺失或错误的值不会在加载连接时立即报错,而是在之后请求时表现为连接或 DNS 错误。
四、配置 CORS
Storage UI 通过预签名 URL 在浏览器中直接上传和预览文件,因此存储桶必须允许你的应用来源(origin)。在 Cloudflare 控制台打开存储桶的 Settings -> CORS Policy 并添加:
[
{
"AllowedOrigins": ["http://localhost:3000", "https://storage.example.com"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE", "HEAD"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3600
}
]把 Storage UI 实际运行的所有来源都列进去,本地开发是 http://localhost:3000,线上则是部署后的地址。来源必须完全匹配,协议和端口都不能差。
DELETE 仅在 Storage UI 设置中开启 客户端直连请求 时才需要,该选项会让应用内添加的连接直接从浏览器访问存储桶。其余方法则始终需要。缺少它们时,列出存储桶仍然可用,但上传和文件预览会因 CORS 报错而失败。
五、可选设置
当 API token 只有读取权限,或不希望用户修改对象时,可以启用只读模式:
STORAGE_1_READ_ONLY=true
如果存储桶通过公开域名或 CDN 访问,可以配置 public base URL:
STORAGE_1_PUBLIC_BASE_URL=https://files.example.com
六、重启 Storage UI
修改 .env.local 后重启开发服务器:
bun run dev托管部署时,保存环境变量并重新部署应用,之后 Cloudflare R2 连接会出现在侧边栏中。
故障排查
存储桶没有出现
确认 bucket name、Account ID、Access Key ID 和 Secret Access Key 都配置在同一个 STORAGE_n_* 编号下。缺少 Account ID 的连接仍可能加载,只是在请求时失败,因此,如果存储桶出现在侧边栏中但打开为空或报错,通常是 STORAGE_n_ACCOUNT_ID 错误或缺失。
访问被拒绝
检查 API token 是否有目标存储桶的访问权限。完整文件管理需要 Object Read & Write 权限。
可以读取但无法上传
确认 STORAGE_n_READ_ONLY 没有设置为 true,并且 API token 包含写入权限。
上传或预览因 CORS 报错
把 Storage UI 运行的来源加入存储桶的 CORS 策略(第四步)。方法中必须包含 GET、PUT、POST 和 HEAD;若开启了 客户端直连请求,还需要 DELETE。
请求出现连接或 DNS 错误
R2 endpoint 会从 STORAGE_n_ACCOUNT_ID 派生为 https://<account-id>.r2.cloudflarestorage.com,这个值在连接加载时不会被验证,因此 Account ID 的拼写错误或缺失只会在实际请求时暴露。