magezero / magento2-cloudflare-r2-storage
Cloudflare R2 storage adapter for Magento 2 media storage
Package info
github.com/zynqa/module-cloudflare-r2-storage
Type:magento2-module
pkg:composer/magezero/magento2-cloudflare-r2-storage
Requires
- php: ^7.4 || ^8.0
- aws/aws-sdk-php: ^3.0
- magento/framework: >=103.0.4
- magento/module-cms: >=104.0.0
- magento/module-media-storage: >=100.4.3
- magento/module-swatches: >=100.4.0
This package is auto-updated.
Last update: 2026-04-23 12:26:23 UTC
README
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)