5 backend types supporting 10+ services: S3, GCS, Azure Blob, Cloudflare R2, MinIO, DigitalOcean Spaces, Backblaze B2, Wasabi, local filesystem, and any HTTP/HTTPS URL.
S3 buckets plus all S3-compatible services: MinIO, Cloudflare R2, DigitalOcean Spaces, Backblaze B2, Wasabi.
GCS with Application Default Credentials, service account keys, or workload identity.
Azure Blob with account key, managed identity, or connection string authentication.
Local disk, Docker volumes, NFS mounts, or EFS. Lowest latency of all backends.
Fetch from any HTTP/HTTPS URL β WordPress, headless CMS, existing CDN, or internal APIs.
| Layer | Method | Best For |
|---|---|---|
| 1. Config Store | Redis + REST API (/api/sources) | Production, multi-tenant, dynamic CRUD |
| 2. YAML file | sources.yml (hot-reloaded) | GitOps, simple deployments |
| 3. Inline config | config.yml sources: | Static fallback, development |
Checked in priority order β Redis overrides YAML which overrides inline. Change storage backends without restarting the service.
Combine multiple backends for different image categories:
/products/width/400/shoe.jpg β Amazon S3
/avatars/cover/100x100/user.jpg β Google Cloud Storage
/blog/width/800/post-header.jpg β WordPress (web proxy)
/static/cdn/logo.png β Local filesystem
/archive/width/600/old-photo.jpg β Azure Blob Storage
The /health endpoint checks connectivity for every configured source in real-time:
GET /health β {
"status": "healthy",
"sources": {
"products": { "status": "ok", "type": "s3", "latencyMs": 45 },
"avatars": { "status": "ok", "type": "gcs", "latencyMs": 62 },
"blog": { "status": "error", "type": "web-proxy", "error": "ECONNREFUSED" }
}
}
Any storage, any cloud, any origin.