We’ve been working on migrating our ActiveStorage provider from AWS S3 to Cloudflare R2. Everything was working correctly, until we got to publicly displaying the images.
You can configure the R2 bucket to use presigned URLs to display images. However, we wanted to use a custom domain on the bucket so that our caching rules would be properly applied.
Note: We don’t have ActiveStorage behind our asset_host
, which is used to serve static content from our site, not the dynamic images uploaded by users.
To address this, we created a service that allows a custom domain to be used for our purpose:
require 'active_storage/service'
require 'active_storage/service/s3_service'
module ActiveStorage
class Service::R2Service < ActiveStorage::Service::S3Service
def initialize(custom_domain:, **args)
# Required values for R2’s S3-compatible usage
args[:force_path_style] = true
args[:request_checksum_calculation] = "when_required"
args[:response_checksum_validation] = "when_required"
args[:region] = "auto"
super(**args)
@custom_domain = custom_domain
end
def url(key, **options)
URI.join(@custom_domain, key).to_s
end
end
end
There are some other options that may need to be considered, but this is the gist of it.
I was wondering if a PR back into Rails would be helpful?