Object Storage
The Rouic Platform provides S3-compatible object storage powered by MinIO. Store files, images, backups, and any other binary data in buckets with fine-grained access control.
Overview
Object storage uses the S3 protocol, which means you can use any existing S3 SDK, CLI tool, or library to interact with it. The storage is backed by MinIO, which provides a fully S3-compatible API.
Endpoint
https://s3.$rouic.comRegion
us-east-1(MinIO convention — server is EU-hosted)
Credentials
Access key and secret key are provided when you create a storage user or bucket via the dashboard.
Max Object Size
5 TB(multipart upload for >5GB)
Creating Buckets
Via the Dashboard
- Navigate to Storage in the sidebar
- Click "Create Bucket"
- Enter a bucket name (lowercase, alphanumeric, hyphens allowed)
- Select an access policy (private or public-read)
- Click "Create"
Via AWS CLI
bash# Configure the CLI aws configure set aws_access_key_id YOUR_ACCESS_KEY aws configure set aws_secret_access_key YOUR_SECRET_KEY # Create a bucket aws s3 mb s3://my-bucket --endpoint-url https://s3.rouic.com # List buckets aws s3 ls --endpoint-url https://s3.rouic.com
Via MinIO CLI (mc)
bash# Add the platform as an alias mc alias set rouic https://s3.rouic.com ACCESS_KEY SECRET_KEY # Create a bucket mc mb rouic/my-bucket # List buckets mc ls rouic
Access Policies
All access requires valid credentials. Objects are not publicly accessible. Use presigned URLs to grant temporary access to specific objects.
Anyone can read objects via their URL. Writing still requires credentials. Use this for public assets, images, or static files.
Public URL format: https://s3.$rouic.com/<bucket>/<key>
Uploading Files
Via the Dashboard
Open a bucket in the dashboard and click "Upload". You can drag and drop files or select them from your file system. Files up to 100 MB can be uploaded through the dashboard.
Via CLI
AWS CLI
bash# Upload a single file aws s3 cp myfile.png s3://my-bucket/images/myfile.png \ --endpoint-url https://s3.rouic.com # Upload a directory aws s3 sync ./public s3://my-bucket/public \ --endpoint-url https://s3.rouic.com # Download a file aws s3 cp s3://my-bucket/images/myfile.png ./download.png \ --endpoint-url https://s3.rouic.com
MinIO CLI
bash# Upload a file mc cp myfile.png rouic/my-bucket/images/myfile.png # Upload a directory recursively mc cp --recursive ./public rouic/my-bucket/public/ # Download mc cp rouic/my-bucket/images/myfile.png ./download.png
Code Examples
Node.js (AWS SDK v3)
import {
S3Client,
PutObjectCommand,
GetObjectCommand,
} from '@aws-sdk/client-s3';
const s3 = new S3Client({
endpoint: 'https://s3.rouic.com',
region: 'us-east-1',
credentials: {
accessKeyId: process.env.S3_ACCESS_KEY,
secretAccessKey: process.env.S3_SECRET_KEY,
},
forcePathStyle: true, // Required for MinIO
});
// Upload a file
await s3.send(new PutObjectCommand({
Bucket: 'my-bucket',
Key: 'images/photo.jpg',
Body: fileBuffer,
ContentType: 'image/jpeg',
}));
// Download a file
const response = await s3.send(new GetObjectCommand({
Bucket: 'my-bucket',
Key: 'images/photo.jpg',
}));
const data = await response.Body.transformToByteArray();Python (boto3)
import boto3
import os
s3 = boto3.client(
's3',
endpoint_url='https://s3.rouic.com',
aws_access_key_id=os.environ['S3_ACCESS_KEY'],
aws_secret_access_key=os.environ['S3_SECRET_KEY'],
region_name='us-east-1',
)
# Upload a file
s3.upload_file('local-file.jpg', 'my-bucket', 'images/photo.jpg')
# Download a file
s3.download_file('my-bucket', 'images/photo.jpg', 'download.jpg')
# List objects
response = s3.list_objects_v2(Bucket='my-bucket', Prefix='images/')
for obj in response.get('Contents', []):
print(obj['Key'], obj['Size'])PHP (AWS SDK)
<?php
use Aws\S3\S3Client;
$s3 = new S3Client([
'endpoint' => 'https://s3.rouic.com',
'region' => 'us-east-1',
'version' => 'latest',
'use_path_style_endpoint' => true,
'credentials' => [
'key' => getenv('S3_ACCESS_KEY'),
'secret' => getenv('S3_SECRET_KEY'),
],
]);
// Upload
$s3->putObject([
'Bucket' => 'my-bucket',
'Key' => 'images/photo.jpg',
'SourceFile' => '/path/to/local/file.jpg',
]);
// Download
$result = $s3->getObject([
'Bucket' => 'my-bucket',
'Key' => 'images/photo.jpg',
]);
$body = $result['Body']->getContents();Go (AWS SDK v2)
package main
import (
"context"
"os"
"strings"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
func main() {
cfg, _ := config.LoadDefaultConfig(context.TODO(),
config.WithRegion("us-east-1"),
config.WithCredentialsProvider(
credentials.NewStaticCredentialsProvider(
os.Getenv("S3_ACCESS_KEY"),
os.Getenv("S3_SECRET_KEY"),
"",
),
),
)
client := s3.NewFromConfig(cfg, func(o *s3.Options) {
o.BaseEndpoint = aws.String("https://s3.rouic.com")
o.UsePathStyle = true
})
// Upload
client.PutObject(context.TODO(), &s3.PutObjectInput{
Bucket: aws.String("my-bucket"),
Key: aws.String("hello.txt"),
Body: strings.NewReader("Hello, World!"),
})
}Ruby (aws-sdk-s3)
require 'aws-sdk-s3'
s3 = Aws::S3::Client.new(
endpoint: 'https://s3.rouic.com',
region: 'us-east-1',
access_key_id: ENV['S3_ACCESS_KEY'],
secret_access_key: ENV['S3_SECRET_KEY'],
force_path_style: true,
)
# Upload
s3.put_object(
bucket: 'my-bucket',
key: 'images/photo.jpg',
body: File.open('photo.jpg', 'rb'),
)
# Download
resp = s3.get_object(bucket: 'my-bucket', key: 'images/photo.jpg')
File.open('download.jpg', 'wb') { |f| f.write(resp.body.read) }Presigned URLs
Presigned URLs allow temporary access to private objects without exposing your credentials. They are useful for:
- Allowing users to download private files
- Allowing users to upload files directly to storage (bypassing your server)
- Generating temporary links for email attachments
Generate a presigned download URL (Node.js)
javascriptimport { getSignedUrl } from '@aws-sdk/s3-request-presigner';
import { GetObjectCommand } from '@aws-sdk/client-s3';
const url = await getSignedUrl(
s3,
new GetObjectCommand({
Bucket: 'my-bucket',
Key: 'private/report.pdf',
}),
{ expiresIn: 3600 } // 1 hour
);
console.log(url);
// https://s3.rouic.com/my-bucket/private/report.pdf?X-Amz-...Generate a presigned upload URL (Node.js)
javascriptimport { getSignedUrl } from '@aws-sdk/s3-request-presigner';
import { PutObjectCommand } from '@aws-sdk/client-s3';
const uploadUrl = await getSignedUrl(
s3,
new PutObjectCommand({
Bucket: 'my-bucket',
Key: 'uploads/user-avatar.jpg',
ContentType: 'image/jpeg',
}),
{ expiresIn: 300 } // 5 minutes
);
// Client can PUT directly to this URLGenerate a presigned URL (Python)
pythonurl = s3.generate_presigned_url(
'get_object',
Params={
'Bucket': 'my-bucket',
'Key': 'private/report.pdf',
},
ExpiresIn=3600, # 1 hour
)
print(url)CORS Configuration
If your web application needs to upload or download files directly from the browser (e.g., using presigned URLs), you need to configure CORS on the bucket.
Set CORS via AWS CLI
bashaws s3api put-bucket-cors \
--endpoint-url https://s3.rouic.com \
--bucket my-bucket \
--cors-configuration '{
"CORSRules": [
{
"AllowedOrigins": ["https://myapp.rouic.com"],
"AllowedMethods": ["GET", "PUT", "POST"],
"AllowedHeaders": ["*"],
"MaxAgeSeconds": 3600
}
]
}'Set CORS via MinIO CLI
bash# Create a cors.json file
cat > cors.json << 'EOF'
{
"CORSRules": [
{
"AllowedOrigins": ["https://myapp.rouic.com"],
"AllowedMethods": ["GET", "PUT", "POST"],
"AllowedHeaders": ["*"],
"MaxAgeSeconds": 3600
}
]
}
EOF
mc anonymous set-json cors.json rouic/my-bucketTip: For development, you can set AllowedOrigins to ["*"]. For production, always restrict to your actual domain.
Next up
API Reference →Previous
Databases