File storage (S3)
Every user gets an S3-compatible bucket of their own. Use it for uploads, media and anything that must outlive a container.
What you get#
When your account is created the platform provisions, on the built-in MinIO:
- a bucket named
<alias>-files; - an IAM user named after your alias, with a policy scoped to that bucket only;
- an access key and secret key for it.
Nobody else can read your bucket and you cannot read theirs. The platform's own bucket (platform, holding build logs and backups) is separate and not reachable with your keys.
Finding your credentials#
Open any project → Settings → S3 storage (your personal bucket). The table shows endpoint, region, bucket, access key and the secret (hidden until you reveal it).
curl -fsS "$BASE/api/v1/users/me/storage" -H "Authorization: Bearer $TOKEN"
get_s3_credentials()
Returns endpoint, region, bucket and both keys. The secret is stable — it does not change between calls.
Using it from your app#
Add s3: true to platform.yaml and the platform injects the credentials on the next deploy or recreate:
| Variable | Meaning |
|---|---|
S3_ENDPOINT |
the MinIO address on the platform network, for example http://172.28.0.5:9000 |
S3_BUCKET |
<alias>-files |
S3_ACCESS_KEY |
your access key |
S3_SECRET_KEY |
your secret key |
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
const s3 = new S3Client({
endpoint: process.env.S3_ENDPOINT, region: "us-east-1", forcePathStyle: true,
credentials: { accessKeyId: process.env.S3_ACCESS_KEY, secretAccessKey: process.env.S3_SECRET_KEY },
});
await s3.send(new PutObjectCommand({ Bucket: process.env.S3_BUCKET, Key: "hello.txt", Body: "hi" }));
import os, boto3
from botocore.config import Config
s3 = boto3.client(
"s3", endpoint_url=os.environ["S3_ENDPOINT"], region_name="us-east-1",
aws_access_key_id=os.environ["S3_ACCESS_KEY"], aws_secret_access_key=os.environ["S3_SECRET_KEY"],
config=Config(s3={"addressing_style": "path"}),
)
s3.put_object(Bucket=os.environ["S3_BUCKET"], Key="hello.txt", Body=b"hi")
Use path-style addressing
Most SDKs default to bucket.endpoint host names, which a private address cannot serve. Switch on path-style (forcePathStyle, addressing_style: path) when you point an SDK at the platform's endpoint.
Things to know#
- The endpoint is an internal address: apps reach it directly, but whether MinIO is also reachable from outside (the console is on port 9001) is an operator decision — ask your administrator.
- The region is the placeholder
us-east-1; MinIO ignores it but most SDKs insist on one. - Your bucket is not part of a project backup. Back it up yourself if it holds the only copy of something important.
- Keys belong to you, not to a project — every project of yours sees the same bucket, so prefix keys per project (
blog/…,shop/…).
