Keep audiobooks in S3-compatible storage
Updated October 27, 2026
Berth can store books in any S3-compatible bucket instead of the server's disk. The server keeps the library and decides who may listen; the audio itself can travel from the bucket or a CDN straight to the phones.
Why object storage
- A small VPS or a Raspberry Pi does not need a big disk.
- Phones download straight from storage, so the server's bandwidth is not the bottleneck.
- The database and its backups stay small; with S3 the server can also put a daily database copy into the bucket.
Supported providers
Any S3-compatible service works. The admin has presets that fill in the endpoint and region for: AWS S3, Cloudflare R2, Yandex Cloud, Backblaze B2, Bunny Storage and MinIO. For Cloudflare R2 there is also a wizard that creates the bucket and keys for you.
Connect a bucket
- Create a bucket and an access key with read and write access to it in your provider's console.
- Add a CORS rule to the bucket: origin is your Berth address, methods GET, HEAD, PUT, headers
*. The admin uploads files from the browser straight to the bucket, so this rule is required. - In the Berth admin open the storage settings, add storage, choose “S3 bucket” and pick a preset or fill in the fields yourself.
- Fill in name, bucket, endpoint (empty for AWS), region (
us-east-1if empty), access key ID and secret access key. Turn on path-style addresses for MinIO; it is turned on by itself for an IP address or localhost. - Press “Check connection”: Berth writes, reads back and deletes a small test file and checks CORS from your server addresses.
- Make the storage the default one: new books go to the default storage.
Keys are stored encrypted with the server key secret.key and are never shown again.
How audio reaches the phones
Without signing, files behind a CDN open by a link that never expires. Their names are SHA-256 hashes and cannot be guessed, but revoking a device does not close links it already has. Bunny CDN token authentication makes links expire after 6 hours.
| Mode | How it works | When to use |
|---|---|---|
| Direct links (default) | Phones get a signed link to the bucket that lasts 15 minutes | Takes the load off the server |
| Through the server | The server streams the file; links last 6 hours and stop working at once when a device is revoked | Phones cannot reach the bucket |
| Through a CDN | Links point to a CDN or a public address of the bucket | Fastest when the bucket has a CDN |
Good to know
- You can have several storages at once; each book shows which one it is in.
- Moving existing books between storages is not available yet: choose the default storage before uploading.
- A storage that holds books cannot be deleted. Removing a profile never deletes files in the bucket.
Questions
Does Berth need public access to the bucket?
No. In the default mode the bucket stays private and phones get signed links that expire after 15 minutes.
The check says the bucket does not accept uploads from a browser. What now?
Add the CORS rule: origin is the Berth address, methods GET, HEAD, PUT, headers *. Then run the check again.