MageZero Cloudflare R2 Storage
magezero/magento2-cloudflare-r2-storage
Stores Magento 2 media files in Cloudflare R2 (S3-compatible) and serves them CDN-first, designed for containerized/Kubernetes deployments with ephemeral storage. Includes Redis-cached CDN existence checks and R2-specific optimizations.
Build Tests
Code Quality
Tested on Magento 2.4.9
Recent Test History
Each release is tested against the latest Magento version at that time.
Share This Module's Status
README
Loaded from GitHubMageZero Cloudflare R2 Storage for Magento 2
Magento 2 module for Cloudflare R2 media storage. Designed for containerized deployments where media is stored in R2 and served via CDN.
Compatibility
Requirements
- PHP: 8.1, 8.2, 8.3, or 8.4
- Magento: 2.4.6 or later
Tested Versions
| Magento | PHP | PHPStan | Unit Tests | Integration Tests |
|---|---|---|---|---|
| 2.4.6-p9 | 8.1 | - | ✓ | ✓ |
| 2.4.7-p4 | 8.2 | - | ✓ | ✓ |
| 2.4.8-p3 | 8.3 | ✓ | ✓ | ✓ |
| 2.4.8-p3 | 8.4 | ✓ | ✓ | - |
Unit tests run on all PHP versions to ensure syntax compatibility. PHPStan runs on PHP 8.3 and 8.4 for static analysis. Integration tests run once per Magento version to verify R2 functionality.
Features
- R2 as Media Storage Backend - All media files stored in Cloudflare R2
- CDN-First Serving - Images served directly from R2/CDN
- Storage-Only Focus - Module handles storage; Magento core handles image processing
- Redis Caching - CDN file existence checks cached for optimal performance
- Docker/Kubernetes Ready - Works with ephemeral containers using tmpfs mounts
- S3-compatible API with Cloudflare R2 optimizations
Installation
Install with Composer in your Magento project:
composer require magezero/magento2-cloudflare-r2-storage
bin/magento module:enable MageZero_CloudflareR2
bin/magento setup:upgrade
bin/magento cache:flush
Configuration
-
Configure R2 Connection:
- Go to Stores > Configuration > Advanced > System > Media Storage Configuration
- Set Media Storage to Cloudflare R2 (S3 Compatible)
-
Configure R2 Credentials:
- Go to Stores > Configuration > MageZero > Cloudflare R2 Storage
- Fill in:
- Account ID (optional if you provide endpoint)
- Endpoint (e.g.
https://<account-id>.r2.cloudflarestorage.com) - Region (use
autofor R2) - Bucket
- Access Key ID / Secret Access Key
- Optional key prefix (e.g.
media)
-
Configure CDN/Public URL (required):
- Set Base Media URL (Secure) to your R2 public domain or Cloudflare CDN URL
- Example:
https://media.example.comorhttps://pub-xxxxx.r2.dev - Optionally set Base Media URL (Unsecure) if needed
-
Configure Caching (optional):
- Adjust File Existence Cache TTL (default: 3600 seconds)
- This caches CDN HEAD requests in Redis for optimal performance
-
Configure Cloudflare R2:
- Set your R2 bucket to Public or configure a custom domain
- Enable Cloudflare CDN caching for best performance
Container Deployment
For containerized deployments (Docker Swarm, Kubernetes), mount a writable tmpfs on pub/media:
Docker Compose / Swarm:
services:
php-fpm:
volumes:
- type: tmpfs
target: /var/www/html/pub/media
Kubernetes:
volumes:
- name: media-cache
emptyDir: {}
volumeMounts:
- name: media-cache
mountPath: /var/www/html/pub/media
How it works:
- Magento core writes to
pub/media(tmpfs - writable, ephemeral) - Module syncs files to R2 for persistent storage
- Images served from R2/CDN
- On container restart, cache regenerates as needed
Product Image Resizing
Pre-generation (Recommended for production):
bin/magento catalog:images:resize
This generates all product image sizes using Magento core, then syncs them to R2.
On-demand generation: When a requested image size doesn't exist in R2, Magento core generates it to the local tmpfs, and subsequent requests are served from R2/CDN once synced.
Architecture
This module focuses solely on storage operations:
- Uploading files to R2
- Downloading files from R2
- Syncing locally generated cache to R2
- File existence checks (cached in Redis)
All image processing (resizing, watermarks, swatch generation) is handled by Magento core. The module intercepts storage operations, not image manipulation.
Notes
- The module uses path-style endpoints by default, which is recommended for R2.
- The Flush Catalog Images Cache action clears cached resized images in R2.
- Redis or similar cache backend recommended for file existence caching.
- R2 bucket must be public or have custom domain configured.
- CAPTCHA images: Magento generates CAPTCHA images locally under
pub/media/captcha/**. If your Base Media URL points at R2/CDN, those images must also exist in R2 to avoid 404s (e.g. admin login CAPTCHA). This module uploads generated CAPTCHA images to R2 when R2 storage is selected. Consider adding an R2 lifecycle rule to expire/delete objects under thecaptcha/prefix.
License
OSL-3.0
Credits
- AWS SDK for PHP (S3 compatible client)
- extdn/github-actions-m2 (CI workflows)
This content is fetched directly from the module's GitHub repository. We are not the authors of this content and take no responsibility for its accuracy, completeness, or any consequences arising from its use.