Project files in object storage (S3-compatible)¶
object_storage is a project-file backend (#86) that stores a project's files in
an S3-compatible bucket — AWS S3, MinIO, Cloudflare R2, Backblaze B2,
Wasabi, or GCS's S3 API — instead of the server's local disk. This fixes
agent-written files being stranded on a (possibly multi-instance) server with no
retrieval path.
The server brokers every read/write through the same internal interface used for
local files, so write_file, the file browser, and the /api/projects/{id}/files
API all work unchanged. Objects are keyed under
<prefix>companies/<companyId>/projects/<projectId>/files/<path>.
Configure (server)¶
| Var | Required | Default | Meaning |
|---|---|---|---|
TRIMUS_PROJECT_S3_BUCKET |
yes | — | bucket name (enabling the backend) |
TRIMUS_PROJECT_S3_PREFIX |
no | trimus-project-files/ |
key prefix (trailing slash added) |
TRIMUS_PROJECT_S3_REGION |
no | us-east-1 |
bucket region |
TRIMUS_PROJECT_S3_ENDPOINT |
no | — | leave empty for AWS S3; set e.g. https://minio.local:9000 or the R2 endpoint |
TRIMUS_PROJECT_S3_PATH_STYLE |
no | false |
true forces path-style addressing (MinIO and most self-hosted gateways) |
Credentials come from the standard AWS chain (AWS_ACCESS_KEY_ID /
AWS_SECRET_ACCESS_KEY / AWS_SESSION_TOKEN, an instance role, or
~/.aws/credentials) — the same as Trimus's encrypted-backup uploads.
If TRIMUS_PROJECT_S3_BUCKET is unset, the backend is simply unavailable and a
project set to object_storage degrades to local-FS with a warning (so a
misconfiguration never breaks file access or blocks startup).
Opt a project (or company) in¶
file_backend lives on projects (and as a per-company default on companies);
a project's value overrides its company's. Switching a backend while files still
exist on the current one is rejected with 409 (no silent orphaning) — empty
or migrate them first.
Notes & limits¶
- Remote workers read/write S3 directly using their own
TRIMUS_PROJECT_S3_*configuration (AWS default credential chain). The server passes only the backend flag plus the company/project IDs (the object-key prefix) in the task payload — the worker never receives S3 credentials over the wire. Server-sidewrite_filealso lands in the same bucket. - Per-file size cap is the same 4 MiB ceiling as local files (simple
PutObject, no multipart needed). - Each project's objects are isolated by the
companies/<co>/projects/<proj>/key prefix; the server is the tenancy authority for which prefix a request hits.