docs/developer/deployment/assets.mdx
By default, files are stored on the local filesystem. For production, use a cloud storage service.
Spree auto-detects the storage provider based on which environment variables are set — no code changes needed. See Environment Variables for the full list.
Set the following environment variables:
| Variable | Default | Description |
|---|---|---|
AWS_ACCESS_KEY_ID | — | AWS access key |
AWS_SECRET_ACCESS_KEY | — | AWS secret key |
AWS_REGION | — | AWS region (e.g., us-east-1) |
AWS_BUCKET | spree-production | S3 bucket name |
The Admin Dashboard uses direct uploads. Configure CORS on your S3 bucket to allow this:
[
{
"AllowedMethods": ["GET", "PUT", "POST"],
"AllowedOrigins": ["https://myspreestore.com"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag"]
}
]
Cloudflare R2 is S3-compatible object storage with zero egress fees and a built-in CDN.
Set the following environment variables:
| Variable | Default | Description |
|---|---|---|
CLOUDFLARE_ENDPOINT | — | R2 endpoint URL |
CLOUDFLARE_ACCESS_KEY_ID | — | R2 access key |
CLOUDFLARE_SECRET_ACCESS_KEY | — | R2 secret key |
CLOUDFLARE_BUCKET | spree-production | R2 bucket name |
Configure CORS on your R2 bucket for direct uploads:
[
{
"AllowedOrigins": [
"https://myspreestore.com"
],
"AllowedMethods": [
"PUT"
],
"AllowedHeaders": [
"*"
],
"ExposeHeaders": [
"Origin",
"Content-Type",
"Content-MD5",
"Content-Disposition"
],
"MaxAgeSeconds": 3600
}
]