S3-compatible object storage for file uploads, assets, and backups.
RaidFrame Object Storage is an S3-compatible storage service for files, images, videos, backups, and static assets. No AWS account needed.
rf add storage
✓ Storage bucket created: my-app-uploads
✓ STORAGE_URL injected into environment
✓ STORAGE_ACCESS_KEY injected
✓ STORAGE_SECRET_KEY injected
Endpoint: https://storage.raidframe.com
Bucket: my-app-uploads
Use any S3 client library. The API is fully compatible with AWS S3.
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
const s3 = new S3Client({
endpoint: process.env.STORAGE_URL,
region: "auto",
credentials: {
accessKeyId: process.env.STORAGE_ACCESS_KEY,
secretAccessKey: process.env.STORAGE_SECRET_KEY,
},
});
await s3.send(new PutObjectCommand({
Bucket: "my-app-uploads",
Key: `avatars/${userId}.jpg`,
Body: fileBuffer,
ContentType: "image/jpeg",
}));
import boto3
s3 = boto3.client("s3",
endpoint_url=os.environ["STORAGE_URL"],
aws_access_key_id=os.environ["STORAGE_ACCESS_KEY"],
aws_secret_access_key=os.environ["STORAGE_SECRET_KEY"],
)
s3.upload_file("local.jpg", "my-app-uploads", "avatars/user1.jpg")
# List files
rf storage ls my-app-uploads/avatars/
# Upload a file
rf storage cp ./image.jpg s3://my-app-uploads/avatars/user1.jpg
# Download a file
rf storage cp s3://my-app-uploads/avatars/user1.jpg ./local.jpg
# Delete a file
rf storage rm s3://my-app-uploads/avatars/user1.jpg
# Sync a directory
rf storage sync ./public/assets s3://my-app-uploads/assets/
# Get storage usage
rf storage info my-app-uploads
Serve files publicly through the global CDN:
storage:
uploads:
type: object
public: true
cdn: true
cors:
origins: ["https://myapp.com"]
methods: ["GET", "PUT"]
Public files are accessible at: https://my-app-uploads.storage.raidframe.com/avatars/user1.jpg
With CDN enabled, files are cached at 40+ edge locations globally.
On-the-fly image transformations via URL parameters:
https://my-app-uploads.storage.raidframe.com/photo.jpg?w=400&h=300&fit=cover&format=webp
| Parameter | Values | Description |
|---|---|---|
w | pixels | Width |
h | pixels | Height |
fit | cover, contain, fill | Resize mode |
format | webp, avif, jpeg, png | Output format |
quality | 1-100 | Compression quality |
blur | 1-250 | Gaussian blur |
Transformed images are cached at the edge. The original is never modified.
Generate time-limited upload/download URLs for direct client-side access:
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const uploadUrl = await getSignedUrl(s3, new PutObjectCommand({
Bucket: "my-app-uploads",
Key: `uploads/${filename}`,
}), { expiresIn: 3600 });
// Return uploadUrl to the client — they upload directly to storage
Automatically delete old files or transition to cheaper storage:
storage:
uploads:
lifecycle:
- prefix: "tmp/"
delete_after: 24h
- prefix: "logs/"
delete_after: 90d
- prefix: "backups/"
transition_to: archive
after: 30d
storage:
uploads:
type: object
public: true
cdn: true
max_file_size: 100MB
allowed_types: ["image/*", "application/pdf", "video/*"]
cors:
origins: ["*"]
methods: ["GET", "PUT", "DELETE"]
versioning: true
| Storage | Price |
|---|---|
| First 5 GB | Free |
| Additional storage | $0.02/GB/mo |
| Bandwidth (CDN) | $0.01/GB |
| Transformations | $0.005/1000 |