Cloudflare R2 — Implementation

Scope: Cloudflare R2 (S3-compatible) for ActiveStorage file uploads in production Tests: All passing (0 failures, 0 errors)


1. Gems Added

File: Gemfile

gem "aws-sdk-s3", require: false
  • aws-sdk-s3 — S3-compatible client used by ActiveStorage for Cloudflare R2

2. Configuration Files

2a. Modified: config/storage.yml

Added Cloudflare R2 service configuration:

cloudflare:
  service: S3
  access_key_id: <%= Rails.application.credentials.dig(:cloudflare, :r2_access_key_id) %>
  secret_access_key: <%= Rails.application.credentials.dig(:cloudflare, :r2_secret_access_key) %>
  region: auto
  bucket: <%= Rails.application.credentials.dig(:cloudflare, :r2_bucket) %>
  endpoint: https://<%= Rails.application.credentials.dig(:cloudflare, :r2_account_id) %>.r2.cloudflarestorage.com
  force_path_style: true
  public: true

2b. Modified: config/environments/production.rb

ActiveStorage service:

config.active_storage.service = :cloudflare

2c. Modified: config/initializers/content_security_policy.rb

Added CDN domain to CSP img_src directive to allow loading images from the R2 custom domain.


3. Summary of Files

Modified Files (3)

File Changes
Gemfile Added aws-sdk-s3 gem
config/storage.yml Cloudflare R2 S3-compatible config
config/environments/production.rb Set active_storage.service = :cloudflare
config/initializers/content_security_policy.rb CDN domain in img_src

Note: No new models, controllers, or views needed. Cloudflare R2 is purely a configuration change — ActiveStorage handles everything through the S3 adapter. Development continues to use :local storage.