存储
配置存储提供商用于文件上传
存储
LaunchSaaS 支持多个存储提供商,具有可扩展的架构。你可以轻松在 S3 兼容的提供商之间切换或添加自定义实现。
支持的提供商
- S3 - AWS S3、Cloudflare R2、MinIO 和其他 S3 兼容服务
- Custom - 使用你自己的存储提供商扩展
配置
在 src/configuration/features.ts 中配置你的存储提供商:
export const features: Features = {
storage: {
provider: "s3", // "s3" | "disabled"
},
// ... 其他功能
};设置 S3 兼容存储
Cloudflare R2(推荐)
- 前往 Cloudflare Dashboard → R2
- 创建存储桶
- 创建具有 R2 权限的 API 令牌
- 添加到你的
.env:
S3_REGION="auto"
S3_BUCKET="your-bucket-name"
S3_ACCESS_KEY_ID="your-access-key-id"
S3_SECRET_ACCESS_KEY="your-secret-access-key"
S3_API_ENDPOINT="https://<account-id>.r2.cloudflarestorage.com"
S3_PUBLIC_ENDPOINT="https://pub-<id>.r2.dev"AWS S3
- 前往 AWS S3 Console
- 创建存储桶
- 创建具有 S3 权限的 IAM 用户
- 添加到你的
.env:
S3_REGION="us-east-1"
S3_BUCKET="your-bucket-name"
S3_ACCESS_KEY_ID="your-access-key-id"
S3_SECRET_ACCESS_KEY="your-secret-access-key"
S3_API_ENDPOINT="https://s3.us-east-1.amazonaws.com"
S3_PUBLIC_ENDPOINT="https://your-bucket-name.s3.us-east-1.amazonaws.com"MinIO(自托管)
- 部署 MinIO 服务器
- 创建存储桶
- 创建访问凭证
- 添加到你的
.env:
S3_REGION="us-east-1"
S3_BUCKET="your-bucket-name"
S3_ACCESS_KEY_ID="your-access-key"
S3_SECRET_ACCESS_KEY="your-secret-key"
S3_API_ENDPOINT="https://your-minio-server.com"
S3_PUBLIC_ENDPOINT="https://your-minio-server.com/your-bucket-name"环境变量
| 变量 | 描述 |
|---|---|
S3_REGION | 区域(例如 us-east-1,R2 使用 auto) |
S3_BUCKET | 存储桶名称 |
S3_ACCESS_KEY_ID | 访问密钥 ID |
S3_SECRET_ACCESS_KEY | 秘密访问密钥 |
S3_API_ENDPOINT | S3 API 端点 URL |
S3_PUBLIC_ENDPOINT | 访问文件的公共 URL |
CORS 配置
对于浏览器上传,在你的存储桶上配置 CORS:
[
{
"AllowedOrigins": ["https://yourdomain.com"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE"],
"AllowedHeaders": ["*"],
"MaxAgeSeconds": 3600
}
]自定义存储提供商
要添加自定义存储提供商:
- 在
src/lib/storage/providers/中创建实现StorageProvider接口的新提供商类 - 在
src/lib/storage/factory.ts中注册 - 添加到
src/schemas/site-configuration.ts中的Features类型
示例:
import { StorageProvider } from "../provider";
export class CustomStorageProvider implements StorageProvider {
async upload(file: File, path: string): Promise<string> {
// 实现上传逻辑
return "https://example.com/file.jpg";
}
async delete(path: string): Promise<void> {
// 实现删除逻辑
}
async getSignedUrl(path: string, expiresIn?: number): Promise<string> {
// 实现签名 URL 生成
return "https://example.com/file.jpg?signature=...";
}
}在工厂中注册:
case "custom":
return new CustomStorageProvider();禁用存储
要禁用存储功能:
export const features: Features = {
storage: {
provider: "disabled",
},
};禁用时,系统使用无操作提供商,将存储操作记录到控制台而不是执行它们。