Active Storage and Cloudflare's R2

I’m starting this topic as an ongoing discussion about using Cloudflare’s R2 service with Active Storage. The objective is to figure which features of Active Storage are supported, which aren’t, and help others configure their apps for use with Cloudflare.

About R2:

R2 is Cloudflare’s object storage solution. It includes “full” S3 compatibility while being much cheaper. Check the announcement below for the full explanation.

Useful links:

Minimal configuration

  service: S3
  access_key_id: YOUR_KEY
  secret_access_key: YOUR_SECRET
  region: auto
  bucket: BUCKET_NAME

For the region attribute, an empty value or us-east-1 are alias to auto.

Active Storage Supported Features

  • Attach: :white_check_mark:
  • Download: :white_check_mark:
  • Display in img tag: :white_check_mark:
  • Direct Upload: :white_check_mark:
  • Public files: :x: (missing ACL support for PutObject operation)

Progressive Migration

In their annoucement, Cloudflare cited the “progressive migration” feature, to make it easier for existing apps to migration away from S3:

Migrations are designed to be dead simple. After specifying an existing storage bucket, R2 will serve requests for objects from the existing bucket, egressing the object only once before copying and serving from R2.

I’ve checked their documentation and everywhere in the R2 dashboard, but found no mention of this feature, so it’s possible it is not available yet.

In the interim, this can be implemented via workers. An explanation can be found below:


Hello, This is very good information. Direct uploads are not working, at least for me. There is a problem with CORS. I think they cannot be defined in Cloudflare yet. Do you know any way to fix this? For example, action text uploads will not work. Thanks!

Same, re CORS. According to the GitHub issue tracker it’s on the roadmap, but no ETA yet.

You don’t need CORS support for direct upload. Just add direct: true to your file upload, and active storage will transparently upload through a signed url. Though it does get a bit more complicated if you are integrating active storage with a frontend library.

How do you it with action text? I get CORS error when dragging files or attaching files. Thanks!

It’s direct_upload: true.

I also get CORS error.

Anyone was able to solve the issue related to CORS?

Looking at the changelog (Changelog · Cloudflare R2 docs), looks like they already support setting CORS via API.

I try to setup, and if I make a GET request, I got this response:

GET /?cors HTTP/1.1
User-Agent: insomnia/2022.6.0

<?xml version="1.0" encoding="UTF-8"?>

But direct upload still not working. I keep getting the CORS error.

I wrote a guide on how to setup ActiveStorage with Cloudflare R2 and how to set CORS using aws-sdk-s3 gem in console:


Exciting news: The S3 to R2 Super Slurper is now Generally Available

Would be interest to see how the brave early-users of this (in conjunction with rails) go! :slight_smile: I think there’s now a UI for configuring CORS too.

The high 4 digits bill to move my files out of AWS to R2 is making me reconsider…

They have a solution to that that is beta now; where they only move files that are requested by your users in real time. In that way you’ll only pay what you would have paid. I guess eventually you’d need to move them all, but you can delay that expense for another time :slight_smile:

Just used your guide to deploy R2 to production. Thanks!