存储提供商
为 @nebutra/uploads 配置 AWS S3、Cloudflare R2 或任何兼容 S3 的后端。
@nebutra/uploads 支持三种存储后端。所有提供商使用相同的 API,唯一区别是设置不同的环境变量。
提供商自动检测优先级:显式设置 STORAGE_PROVIDER 环境变量 → 存在 AWS_BUCKET_NAME → 存在 R2_ACCOUNT_ID → 内存模式兜底(仅限开发环境)。
AWS S3
默认提供商。当你已在 AWS 生态系统中深度投入或需要精细的 IAM 策略时,使用 S3。
环境变量
STORAGE_PROVIDER=s3
AWS_BUCKET_NAME=nebutra-uploads
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=...配置步骤
在 AWS 控制台中,前往 S3 → 创建存储桶。
- 存储桶名称:
nebutra-uploads(或你偏好的名称) - 区域: 选择距离你应用最近的区域
- 阻止公共访问: 除非需要公共 CDN,否则保持全部阻止
- 版本控制: 可选,生产环境推荐开启
前往 IAM → 用户 → 创建用户,附加以下内联策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::nebutra-uploads",
"arn:aws:s3:::nebutra-uploads/*"
]
}
]
}为该用户生成访问密钥,并将其保存为 AWS_ACCESS_KEY_ID 和 AWS_SECRET_ACCESS_KEY。
在 S3 存储桶设置中,前往 权限 → CORS 配置,添加:
[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE", "HEAD"],
"AllowedOrigins": ["https://app.nebutra.com"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3600
}
]将 AllowedOrigins 替换为你的应用域名。本地开发时添加 http://localhost:3000。
将四个变量添加到 Vercel 项目(或本地开发的 .env.local)并重新部署。
费用说明
AWS S3 按存储量(GB/月)、PUT/GET 请求数和出站流量计费。对于读取频繁的工作负载,建议在 S3 前部署 CloudFront 以降低出站费用。
Cloudflare R2
R2 兼容 S3 协议,且零出站费用。当降低带宽成本是首要考虑,或应用运行在 Cloudflare Workers 上时,使用 R2。
环境变量
STORAGE_PROVIDER=r2
R2_BUCKET_NAME=nebutra-uploads
R2_ACCOUNT_ID=your-cloudflare-account-id
R2_ACCESS_KEY_ID=...
R2_SECRET_ACCESS_KEY=...
R2_PUBLIC_URL=https://assets.nebutra.comR2_PUBLIC_URL 是用于提供公共文件服务的自定义域名或 r2.dev 子域名。设置后,公共资源可通过 CDN 直接分发,无需签名 URL。
配置步骤
在 Cloudflare 控制台中,前往 R2 → 创建存储桶。
- 存储桶名称:
nebutra-uploads - 位置: 自动(或选择特定区域)
前往 R2 → 管理 R2 API 令牌 → 创建 API 令牌。
- 权限: 对象读写
- 存储桶: 限定为
nebutra-uploads
保存访问密钥 ID 和密钥。
在 R2 存储桶设置中,前往 设置 → CORS 策略:
[
{
"AllowedOrigins": ["https://app.nebutra.com"],
"AllowedMethods": ["GET", "PUT", "HEAD", "DELETE"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3600
}
]如果需要公共 CDN URL 提供资源(头像、公共文档),前往 R2 存储桶 → 设置 → 公共访问,连接自定义域名或开启 r2.dev 子域名。将 R2_PUBLIC_URL 设置为该 URL。
将五个变量添加到 Vercel 并重新部署。R2_ACCOUNT_ID 可在 Cloudflare 控制台首页查看。
费用说明
R2 无出站费用,只按存储量和操作次数计费。对于大多数有中等文件访问量的 SaaS 应用,考虑出站费用后 R2 比 S3 便宜得多。
兼容 S3 的提供商
任何兼容 S3 的服务都可与 @nebutra/uploads 配合使用,包括 Backblaze B2、MinIO、DigitalOcean Spaces、Wasabi 等。
环境变量
STORAGE_PROVIDER=s3-compatible
AWS_BUCKET_NAME=nebutra-uploads
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=...
AWS_SECRET_ACCESS_KEY=...
S3_ENDPOINT_URL=https://s3.us-east-005.backblazeb2.comS3_ENDPOINT_URL 会覆盖默认的 AWS 端点地址。将其设置为你的提供商的兼容 S3 端点 URL。
Backblaze B2
在 Backblaze 控制台中,前往 B2 云存储 → 创建存储桶。创建完成后记录显示的端点 URL(如 s3.us-east-005.backblazeb2.com)。
前往 应用密钥 → 添加新应用密钥,限定到你的存储桶,保存 keyID 和 applicationKey。
STORAGE_PROVIDER=s3-compatible
AWS_BUCKET_NAME=nebutra-uploads
AWS_REGION=us-east-005
AWS_ACCESS_KEY_ID=<keyID>
AWS_SECRET_ACCESS_KEY=<applicationKey>
S3_ENDPOINT_URL=https://s3.us-east-005.backblazeb2.comMinIO(自托管)
docker run -p 9000:9000 -p 9001:9001 \
-e MINIO_ROOT_USER=admin \
-e MINIO_ROOT_PASSWORD=password \
quay.io/minio/minio server /data --console-address ":9001"在 http://localhost:9001 打开 MinIO 控制台。创建名为 nebutra-uploads 的存储桶,并生成访问密钥对。
STORAGE_PROVIDER=s3-compatible
AWS_BUCKET_NAME=nebutra-uploads
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=<minio-access-key>
AWS_SECRET_ACCESS_KEY=<minio-secret-key>
S3_ENDPOINT_URL=http://localhost:9000本地 MinIO 需要设置 S3_FORCE_PATH_STYLE=true,以避免虚拟托管样式 URL 解析问题。
切换提供商
由于所有提供商使用同一套 @nebutra/uploads API,切换只需更新环境变量,无需修改任何应用代码。
# 从 S3 切换到 R2 — 只需更新环境变量
STORAGE_PROVIDER=r2
R2_BUCKET_NAME=nebutra-uploads
R2_ACCOUNT_ID=...
R2_ACCESS_KEY_ID=...
R2_SECRET_ACCESS_KEY=...
R2_PUBLIC_URL=https://assets.nebutra.comHow is this guide?
最后更新于