Storage
Configure storage providers for file uploads
Storage
LaunchSaaS supports multiple storage providers with an extensible architecture. You can easily switch between S3-compatible providers or add custom implementations.
Supported Providers
- S3 - AWS S3, Cloudflare R2, MinIO, and other S3-compatible services
- Custom - Extend with your own storage provider
Configuration
Configure your storage provider in src/configuration/features.ts:
export const features: Features = {
storage: {
provider: "s3", // "s3" | "disabled"
},
// ... other features
};Setup S3-Compatible Storage
Cloudflare R2 (Recommended)
- Go to Cloudflare Dashboard → R2
- Create a bucket
- Create an API token with R2 permissions
- Add to your
.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
- Go to AWS S3 Console
- Create a bucket
- Create an IAM user with S3 permissions
- Add to your
.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 (Self-Hosted)
- Deploy MinIO server
- Create a bucket
- Create access credentials
- Add to your
.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"Environment Variables
| Variable | Description |
|---|---|
S3_REGION | Region (e.g., us-east-1, auto for R2) |
S3_BUCKET | Bucket name |
S3_ACCESS_KEY_ID | Access key ID |
S3_SECRET_ACCESS_KEY | Secret access key |
S3_API_ENDPOINT | S3 API endpoint URL |
S3_PUBLIC_ENDPOINT | Public URL for accessing files |
CORS Configuration
For browser uploads, configure CORS on your bucket:
[
{
"AllowedOrigins": ["https://yourdomain.com"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE"],
"AllowedHeaders": ["*"],
"MaxAgeSeconds": 3600
}
]Custom Storage Provider
To add a custom storage provider:
- Create a new provider class in
src/lib/storage/providers/implementing theStorageProviderinterface - Register in
src/lib/storage/factory.ts - Add to the
Featurestype insrc/schemas/site-configuration.ts
Example:
import { StorageProvider } from "../provider";
export class CustomStorageProvider implements StorageProvider {
async upload(file: File, path: string): Promise<string> {
// Implement upload logic
return "https://example.com/file.jpg";
}
async delete(path: string): Promise<void> {
// Implement delete logic
}
async getSignedUrl(path: string, expiresIn?: number): Promise<string> {
// Implement signed URL generation
return "https://example.com/file.jpg?signature=...";
}
}Register in factory:
case "custom":
return new CustomStorageProvider();Disable Storage
To disable storage functionality:
export const features: Features = {
storage: {
provider: "disabled",
},
};When disabled, the system uses a no-op provider that logs storage operations to console instead of executing them.