-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Description
🔖 Feature description
Add native support for AWS S3 and S3-compatible storage services (like MinIO, DigitalOcean Spaces, Backblaze B2) as an alternative to the existing Cloudflare R2 and local storage options.
Key capabilities:
- Generic
s3storage provider using AWS SDK v3 - Support for custom endpoints (MinIO, self-hosted S3-compatible services)
- Multipart upload support for large files (videos up to 1GB)
- Date-based directory organization (
YYYY/MM/DD/filename) matching local storage pattern - Automatic file deletion from storage when media is deleted in Postiz
- Full backward compatibility with existing
localandcloudflareproviders
🎤 Why is this feature needed ?
1. Infrastructure flexibility:
Many self-hosted users already have existing S3-compatible storage infrastructure (AWS S3, MinIO, DigitalOcean Spaces) and prefer not to set up a separate Cloudflare R2 account just for Postiz.
2. Cost optimization:
- AWS S3 may be cheaper for users already in the AWS ecosystem
- MinIO allows completely self-hosted object storage with no external dependencies
- Organizations with existing S3 buckets can reuse them
3. Data sovereignty:
Self-hosted MinIO allows users to keep all media files on their own infrastructure, which is critical for:
- GDPR compliance
- Enterprise security requirements
- Air-gapped environments
4. Vendor neutrality:
Currently Postiz only supports Cloudflare R2 for cloud object storage. Adding S3 support provides users with more choices.
✌️ How do you aim to achieve this?
New environment variables:
STORAGE_PROVIDER="s3"
S3_ENDPOINT="" # Optional: Custom endpoint for MinIO/compatible services
S3_ACCESS_KEY="your-key"
S3_SECRET_KEY="your-secret"
S3_BUCKET="your-bucket"
S3_REGION="us-east-1"
S3_BUCKET_URL="" # Optional: Custom public URL (CDN/proxy)Implementation approach:
- Create
S3Storageclass implementing existingIUploadProviderinterface - Create
S3Uploaderclass for multipart uploads (mirroring R2 uploader) - Add
's3'case toUploadFactory(factory pattern) - Route uploads in
MediaControllerbased onSTORAGE_PROVIDERenv var - Frontend uses same
AwsS3MultipartUppy plugin (S3 API compatible)
Configuration examples:
AWS S3:
STORAGE_PROVIDER="s3"
S3_ACCESS_KEY="AKIAIOSFODNN7EXAMPLE"
S3_SECRET_KEY="wJalrXUtnFEMI/..."
S3_BUCKET="my-postiz-bucket"
S3_REGION="us-west-2"
S3_BUCKET_URL="https://my-postiz-bucket.s3.us-west-2.amazonaws.com"MinIO (self-hosted):
STORAGE_PROVIDER="s3"
S3_ENDPOINT="https://minio.example.com"
S3_ACCESS_KEY="minioadmin"
S3_SECRET_KEY="minioadmin"
S3_BUCKET="postiz"
S3_REGION="us-east-1"
S3_BUCKET_URL="https://minio.example.com/postiz"🔄️ Additional Information
Backward compatibility:
- Existing
localandcloudflareproviders remain unchanged - No database migrations required
- Same media table schema (stores full URLs)
Bug fixes included:
- Enabled actual file deletion from Cloudflare R2 (was previously a no-op)
- Added file deletion from local storage when media is deleted
- Fixed URL trailing slash handling for all providers
Requirements for MinIO /S3 users:
- Bucket must have public read access enabled:
mc anonymous set download myminio/bucket-name - This is similar to R2's public access requirement
Testing performed:
- ✅ Local storage upload/delete
- ✅ AWS S3 upload/delete
- ✅ MinIO upload/delete
- ✅ Multipart upload for large videos
- ✅ Cloudflare R2 regression test
👀 Have you spent some time to check if this feature request has been raised before?
- I checked and didn't find similar issue
Are you willing to submit PR?
Yes I am willing to submit a PR!