Request addressing & custom domains
TinyS3 supports both S3 request styles and per-bucket custom domains, so applications that need bucket-specific DNS endpoints work unchanged, with a certificate per domain.
Path-style (default)
https://<host>/<bucket>/<key> — always available, needs no configuration. The bucket is the first path segment.
Reserved bucket names
Because the bucket is the first path segment, a handful of top-level paths the server already serves for itself would collide with a bucket of the same name and be unreachable path-style. Those names are reserved — creating a bucket with one is rejected with 400 InvalidBucketName:
| Reserved name | Serves |
|---|---|
console | the web console UI (/console/) |
rest | the admin REST API (/rest/) |
tinys3 | health & metrics endpoints (/tinys3/health/…, /tinys3/metrics) |
mcp | the MCP server, only when the MCP plugin is loaded |
Any additional plugin that registers a top-level route reserves its own name the same way while it is loaded. The reservation applies to both request styles. Virtual-host and custom-domain addressing are unaffected — a bucket reachable only as console.s3.example.com never collides with the path-style /console route, but the name is still reserved so the bucket stays reachable path-style too.
Virtual-host style
https://<bucket>.<domain>/<key> — the bucket is the left-most label of the Host header. This is what the AWS SDKs use by default, so enabling it lets a default-configured SDK talk to TinyS3 without forcePathStyle.
Turn it on by setting one or more base domains:
bash
# environment (comma-separated) base domains
TINY_S3_DOMAIN=s3.example.com,s3.internalyaml
# or in config
server:
domains: [s3.example.com]With s3.example.com set, bucket.s3.example.com resolves to the bucket bucket; the bare s3.example.com stays path-style (so GET s3.example.com/ is ListBuckets). Only a single left-most label is treated as a bucket — a.b.s3.example.com is not routed as a bucket. Point wildcard DNS (*.s3.example.com) at the server. SigV4 is unaffected: the client signs the Host it sends, and the server verifies against it before resolving the bucket.
Custom domain per bucket
Map an arbitrary FQDN to a bucket so clients reach it as https://assets.example.com/logo.png — the domain replaces the bucket. Managed per bucket via ?customDomain (owner-only, like the other bucket-config sub-resources):
PUT /<bucket>?customDomain <CustomDomainConfiguration><Domain>assets.example.com</Domain></CustomDomainConfiguration>
GET /<bucket>?customDomain
DELETE /<bucket>?customDomainA domain can map to only one bucket (a second claim is rejected). Point that domain's DNS at the server and, for browser use, make the objects public (a public-read bucket policy) or sign requests.
If the bucket also has a website configuration, the mapped domain is served as a static website: https://<domain>/ resolves to the index document and missing keys return the error document. This Host-based website serving runs ahead of the console/REST routing, so / and /index.html on the mapped domain are the bucket's objects, not the console. Enabling a website grants no public access on its own — you still need a public-read policy (or signed requests). The bare API host is not a website endpoint; use the mapped domain. Mappings resolve in one storage read, cached briefly, and work identically on a single node or a cluster (they live in the quorum-replicated system store). A custom domain must not sit under a configured base domain — the base-domain wildcard claims all its subdomains as virtual-host buckets.
Per-domain TLS certificates (SNI)
Serve many domains, each with its own certificate, on one port — the certificate is chosen per connection from the TLS SNI hostname, with a default for anything unmatched:
yaml
server:
tls:
enabled: true
certFile: /etc/tinys3/default.crt # default (unmatched SNI)
keyFile: /etc/tinys3/default.key
certs:
- hosts: [assets.example.com]
certFile: /etc/tinys3/assets.crt
keyFile: /etc/tinys3/assets.key
- hosts: ["*.shop.example.com"] # wildcards allowed
certFile: /etc/tinys3/shop.crt
keyFile: /etc/tinys3/shop.keyOmit certs for the ordinary single-certificate setup.