Storage
S3-compatible storage driver loading, MinIO locally, and object-key multi-tenancy.
Toast uses a pluggable storage driver for uploads. Like email, the storage loader receives its configuration explicitly from the API config layer.
Loader API
const driver = await getStorageDriver({
driverName: config.drivers.storageDriver,
driverConfig: config.drivers.s3,
});If no storage driver is configured, the loader returns null.
Selection logic
| Driver name | Result |
|---|---|
null | storage not configured |
toast-driver-storage-s3 | S3-compatible storage driver |
There is no built-in in-memory or console storage driver. Local development uses MinIO so the storage path matches production-style S3 behavior.
Object key pattern
Stored object keys are namespaced by site:
{siteId}/images/{year}/{month}/{nanoid}.{ext}That provides tenant-specific organization, but authorization is still enforced at the controller layer. Upload and delete actions use the authenticated session’s siteId.
S3-compatible providers
The shipped S3 driver works with:
- MinIO
- AWS S3
- Cloudflare R2
- Backblaze B2
In the Toast repo, toast-driver-storage-s3 already exists as a workspace package under drivers/storage-s3/ and is already referenced by apps/api.
If you are working outside this monorepo, install the package in the application that loads the driver.
Relevant config values:
STORAGE_DRIVER=toast-driver-storage-s3S3_ENDPOINTS3_ACCESS_KEY_IDS3_SECRET_ACCESS_KEYS3_BUCKETS3_REGIONS3_PUBLIC_URL
Local development
MinIO is started by pnpm dx. That gives local development the same S3-style API shape used in production.
Custom storage drivers
Like email drivers, custom storage drivers should accept a config object in their constructor rather than reading env directly.
Troubleshooting
- storage driver not configured — set
STORAGE_DRIVER - package not found — install the driver package in the workspace
- AccessDenied — verify credentials, bucket, and endpoint
- public URLs broken — verify
S3_PUBLIC_URL