Notes to self

Setting up Cloudflare R2 buckets for Active Storage

Rails comes with a built-in support for saving and uploading files to S3 and S3-compatible storage services in Active Storage. Here’s how to set up Cloudflare R2.

Cloudflare R2

To start using Cloudflare R2, select R2 Object Storage from the menu on the left navbar. If you are on free plan you’ll need to subscribe first.

Then you can click + Create bucket and give your bucket a name. Choose meaningful names for your buckets. I usually append the environment to the name.

Cloudflare will auto assign your bucket location based on your actual location and providing a hint might not work. Not great doing this on holidays.

TIP: If you are hosting in EU, you can at least choose Specify jurisdiction and force it to be within EU.

Then on the bucket page choose Settings and include the following CORS:

[
  {
    "AllowedOrigins": [
      "*"
    ],
    "AllowedMethods": [
      "PUT"
    ],
    "AllowedHeaders": [
      "*"
    ],
    "ExposeHeaders": [
      "Origin", "Content-Type", "Content-MD5", "Content-Disposition"
    ],
    "MaxAgeSeconds": 3600
  }
]

Once done click on API next to the + Create Bucket button. Select Manage API tokens and create a new token.

Note all secrets and most importantly access key, access key secret and URL.

Rails configuration

Install Active Storage and configure config/storage.yml similarly to the following:

test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

cloudflare_dev:
  service: S3
  endpoint: https://[HASH].eu.r2.cloudflarestorage.com
  access_key_id: <%= ENV["R2_ACCESS_KEY"] %>
  secret_access_key: <%= ENV["R2_SECRET_ACCESS_KEY"] %>
  bucket: app-dev
  region: auto

cloudflare_production:
  endpoint: https://[HASH].eu.r2.cloudflarestorage.com
  access_key_id: <%= ENV["R2_ACCESS_KEY"] %>
  secret_access_key: <%= ENV["R2_SECRET_ACCESS_KEY"] %>
  bucket: app
  region: auto

To connect Cloudflare we’ll need an endpoint, access_key_id, secret_access_key, and region. You can use environment variables or Rails Credentials.

Note that unlike for Amazon S3 where we fill in the region and Digital Ocean Spaces where the region is unused, we set it to auto.

I usually set up two different backends, one for development and one for production:

# config/environments/development.rb
config.active_storage.service = :cloudflare_dev

# config/environments/production.rb
config.active_storage.service = :cloudflare_production

And that’s really it!

Check out my book
Interested in Ruby on Rails default testing stack? Take Minitest and fixtures for a spin with my latest book.

Get Test Driving Rails and make your tests faster and easier to maintain.

by Josef Strzibny
RSS