Sally storage
Sally supports local upload storage by default and an S3-compatible object storage backend for managed assets.
The storage layer is intentionally provider-neutral. It can be used with AWS S3, Cloudflare R2, MinIO, Wasabi, DigitalOcean Spaces, and Hetzner Object Storage.
Local default
SALLY_STORAGE_DRIVER=local
# optional, defaults to the app working directory
SALLY_STORAGE_LOCAL_ROOT=/var/lib/sally
Local files are served through Sally /uploads/... routes.
S3-compatible backend
SALLY_STORAGE_DRIVER=s3
SALLY_STORAGE_S3_ENDPOINT=https://fsn1.your-objectstorage.com
SALLY_STORAGE_S3_REGION=fsn1
SALLY_STORAGE_S3_BUCKET=sally-assets
SALLY_STORAGE_S3_ACCESS_KEY_ID=...
SALLY_STORAGE_S3_SECRET_ACCESS_KEY=...
SALLY_STORAGE_S3_FORCE_PATH_STYLE=true
# optional but recommended for email images/CDN delivery
SALLY_STORAGE_S3_PUBLIC_BASE_URL=https://sally-assets.fsn1.your-objectstorage.com
If SALLY_STORAGE_S3_PUBLIC_BASE_URL is set, uploaded assets are stored with public URLs. If it is not set, Sally keeps using its /uploads/... URLs and proxies reads through the API.
Hetzner Object Storage
Use the S3-compatible settings above. Choose the Hetzner endpoint and region matching your bucket, for example an EU region such as fsn1 or nbg1 depending on your Hetzner setup.
Recommended for Sally Marketing email assets:
- keep buckets private unless you intentionally use a public asset domain
- configure
SALLY_STORAGE_S3_PUBLIC_BASE_URLto a stable public/CDN URL for images embedded in emails - keep image compression enabled in Sally before upload
Current consumers
- Marketing media library and email image uploads
The same abstraction is intended for task/project/profile uploads in a follow-up migration.