DinD HostingManual
CHAPTER 09

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).

hosting.example.com/projects/7
Settings
The Settings tab. The endpoint is reachable from your app containers; the secret is revealed on demand.
bash
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
js
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" }));
python
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/…).