Configuration
Which backend a project uses, and what the S3 one needs to reach its bucket.
Settings
| Setting | Default | Meaning |
|---|---|---|
STORAGE_BACKEND |
s3 with this component, filesystem without it |
Which backend get_storage() builds |
STORAGE_ROOT |
storage_data |
Where the filesystem backend keeps objects |
S3_ENDPOINT_URL |
http://seaweedfs:8333 in compose |
The endpoint to talk to; empty for AWS |
S3_BUCKET |
the project slug | Created on first use if missing |
S3_ACCESS_KEY |
placeholder for SeaweedFS | Real credentials in production |
S3_SECRET_KEY |
placeholder for SeaweedFS | Real credentials in production |
S3_REGION |
us-east-1 |
|
S3_PATH_STYLE |
true |
Path-style addressing; most self-hosted stores need it |
Without the component, STORAGE_BACKEND=filesystem and the S3 settings are ignored. That is a working default, not a placeholder: content-addressed keys mean a project can run on disk for as long as it likes.
Pointing at a Real Store
Path style is the setting people get wrong
Virtual-host addressing puts the bucket in the hostname (my-app.s3.example.com), which self-hosted stores usually cannot serve and TLS certificates usually do not cover. Leave S3_PATH_STYLE=true for anything that is not AWS.
The Bucket
The backend creates the bucket on first use if it is missing, so a fresh dev stack needs no setup step. In production that means the credentials need CreateBucket, or the bucket should exist already. The health check reports which state it found.
The Dev Container
seaweedfs:
image: chrislusf/seaweedfs:4.45
command: server -s3 -dir=/data -ip=seaweedfs -ip.bind=0.0.0.0 -master.volumeSizeLimitMB=1024
environment:
- AWS_ACCESS_KEY_ID=${S3_ACCESS_KEY:-aegis}
- AWS_SECRET_ACCESS_KEY=${S3_SECRET_KEY:-aegis-secret}
SeaweedFS takes the app's own S3_ACCESS_KEY and S3_SECRET_KEY as its admin identity, so it answers only to those credentials. Without an identity it treats every request as anonymous: any key is accepted, and listing buckets returns nothing, because an anonymous caller owns none. With auth on, / answers 403, so the healthcheck probes /healthz.
Only the S3 port is published, and the data lives in a named volume that survives make restart and is removed by make clean. It is a dev dependency: production points the same settings at a real store and does not run this service.
Health
The dashboard's storage card reports the backend in use, the endpoint, the bucket, whether it is reachable, and object counts when the documents service is present. A store that cannot be reached shows as unhealthy there rather than failing at the moment someone uploads a file.
With the htmx frontend, Overseer's Storage page shows the app's bucket (object count, bytes stored, largest object, a size histogram and the connection) and a Browse section: every bucket the credentials can see, folder by folder, with download, upload into the open folder, and delete (one file from its row menu, or the checked ones at once). S3 has no folders; the browser draws the common prefixes a / delimiter returns, as every console does. The app's own bucket is read-only there: its keys are content hashes that database rows point at, so only the app writes it.
Next Steps
| Topic | Description |
|---|---|
| Examples | Using storage from a service, and moving an existing project |
| Getting Started | The protocol and content-addressed keys |
Related:
- Documents Service - The largest consumer