staqlydocs

Media storage

Keep uploaded pictures and videos on the server's disk or in any S3-compatible bucket (AWS S3, Cloudflare R2, MaxIOFS), and move existing files between them.

Edit on GitHub

Everything people upload (pictures, videos, files) and the thumbnails made from them live in one place, picked with STORAGE_DRIVER:

STORAGE_DRIVERWhere files liveFor
disk (default)UPLOAD_DIR, by default uploads/ in the data directoryMost installs: the binary or the Docker container
s3An S3-compatible bucketStorage that grows without a bigger disk, or media kept off the machine

Nothing else changes: the dashboard, the API, MCP and the SDKs work the same with either.

Use a bucket

Set these in the server's environment (-e or --env-file with Docker, exported before staqly serve with the binary; see Configuration) and restart:

staqly.env
STORAGE_DRIVER=s3
S3_ENDPOINT=https://s3.eu-central-1.amazonaws.com
S3_REGION=eu-central-1
S3_BUCKET=my-staqly-media
S3_ACCESS_KEY_ID=AKIA...
S3_SECRET_ACCESS_KEY=...

The server checks the bucket on start and refuses to run when a setting is missing or the bucket can't be reached, with the reason in the log. A missing bucket is created only with S3_CREATE_BUCKET=true.

ProviderS3_ENDPOINTNotes
AWS S3https://s3.<region>.amazonaws.comSet S3_REGION to the bucket's region.
Cloudflare R2https://<account id>.r2.cloudflarestorage.comS3_REGION=auto. No egress fees, which helps: platforms download every published file.
MaxIOFS, MinIO, Garage, SeaweedFShttp://<host>:<port>Set S3_FORCE_PATH_STYLE=true.

S3_PREFIX keeps staqly's files in a folder of a shared bucket (staqly/).

The access key needs to read, write, delete and list objects in the bucket (on AWS: s3:GetObject, s3:PutObject, s3:DeleteObject, s3:ListBucket), plus s3:CreateBucket if you use S3_CREATE_BUCKET. The bucket can stay private.

How files reach people and platforms

  • The dashboard and the API stream files from the bucket themselves, with the same access checks as on disk: a file is found through its workspace first, never by its name in the bucket. Video seeking works (ranged reads), and the bucket needs no CORS settings.
  • Platforms that download media themselves get a signed link to the bucket that works for two hours. With S3_PUBLIC_URL (a CDN in front of a public bucket) they get a plain link there instead.
  • Thumbnails are made on first use and kept next to the files.

Every workspace has its own folder in the store, on disk and in a bucket alike: workspaces/<id>/media/ (the uploads), workspaces/<id>/thumbs/ (thumbnails, a cache) and workspaces/<id>/projects/ (media editor projects). Files from versions before these folders are moved into them on the first start after the upgrade.

Move existing files into a bucket

Switching from disk to a bucket doesn't move the files by itself. Copy them with:

docker exec staqly server storage migrate --dry-run   # what would be copied
docker exec staqly server storage migrate             # copy UPLOAD_DIR into the bucket

Run it with the new STORAGE_DRIVER=s3 settings in place. Files already in the bucket are skipped, so a run that stopped half way continues where it left off, and running it twice copies nothing. --from <folder> copies another folder, for example the uploads of a backup. The files on disk stay where they are until you delete them.

Backups

With disk, the uploads folder is part of the data directory you back up (see Backup & restore). With s3, the database backup no longer contains the files: protect the bucket with your provider's tools (versioning, replication or a lifecycle copy to a second bucket). The workspace export with files (POST /v1/workspace/export) reads them from the bucket either way.

Development

The development stack (make dev) runs MaxIOFS and keeps media there, so the bucket path is the one you test every day. See Docker Compose.

On this page