Skip to main content
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.

AWS S3

Set the following environment variables:
VariableDefaultDescription
AWS_ACCESS_KEY_IDAWS access key
AWS_SECRET_ACCESS_KEYAWS secret key
AWS_REGIONAWS region (e.g., us-east-1)
AWS_BUCKETspree-productionS3 bucket name

CORS Configuration

The Admin Dashboard uses direct uploads. Configure CORS on your S3 bucket to allow this:
  1. Go to your S3 bucket in AWS Console
  2. Click on “Permissions” tab
  3. Scroll down to “Cross-origin resource sharing (CORS)”
  4. Click “Edit” and paste the following configuration:
[
  {
    "AllowedMethods": ["GET", "PUT", "POST"],
    "AllowedOrigins": ["https://myspreestore.com"],
    "AllowedHeaders": ["*"],
    "ExposeHeaders": ["ETag"]
  }
]
Replace myspreestore.com with the domain you use to access your Spree Admin Dashboard.

Cloudflare R2

Cloudflare R2 is S3-compatible object storage with zero egress fees and a built-in CDN. Set the following environment variables:
VariableDefaultDescription
CLOUDFLARE_ENDPOINTR2 endpoint URL
CLOUDFLARE_ACCESS_KEY_IDR2 access key
CLOUDFLARE_SECRET_ACCESS_KEYR2 secret key
CLOUDFLARE_BUCKETspree-productionR2 bucket name

CORS Configuration

Configure CORS on your R2 bucket for direct uploads:
  1. Go to your R2 bucket in Cloudflare Console
  2. Click on “Settings” tab
  3. Scroll down to “CORS policy”
  4. Click “Edit CORS policy” and paste the following configuration:
[
  {
    "AllowedOrigins": [
      "https://myspreestore.com"
    ],
    "AllowedMethods": [
      "PUT"
    ],
    "AllowedHeaders": [
      "*"
    ],
    "ExposeHeaders": [
      "Origin",
      "Content-Type",
      "Content-MD5",
      "Content-Disposition"
    ],
    "MaxAgeSeconds": 3600
  }
]
Replace myspreestore.com with the domain you use to access your Spree Admin Dashboard.