Active Storage のアップロード先として Cloudflare R2 を使う方法
Amazon S3 互換のAPIを備えるオブジェクトストレージである Cloudflare R2 がオープンβなったことで注目を集めていますね。
Amazon S3 互換ということは、Active StorageのS3サービスでファイルのアップロード先として R2 を使用できるはずです。試してみました。
利用方法
1. R2 の準備
アクセスキーの取得
Manage R2 API Tokens をクリック
Create API token をクリック
バケットへのアップロードを行いたいので Edit: Allow List, Write, and Delete operations of all buckets を選択して Create API Token
Secret Access Key と Access Key ID を控える
アカウントIDの取得
R2のダッシュボード右の Account ID を控える
バケットの作成
Create a bucket をクリックし、バケット名を指定、作成する
2. config/storage.yml の変更
準備しておいたアクセスキーなどを設定します。
region: auto
と force_path_style: true
が必要なことに注意して下さい。(設定値は Aws::S3::Client.new にそのまま渡されるので、AWS SDKのドキュメントを確認してください。)
# config/storage.yml
cloudflare:
service: S3
access_key_id: <Access Key ID>
secret_access_key: <Secret Access Key>
endpoint: https://<Account ID>.r2.cloudflarestorage.com
bucket: <バケット名>
region: auto
force_path_style: true
なお、実際にはキーはべた書きせず Credentials を使うのが一般的かと思います。
3. config/environments/development.rb の変更
config/storage.yml
に記載したサービスを使うように変更します。
config.active_storage.service = :cloudflare
# 2022年9月の一般公開にあわせて署名付きURLに対応したため、この設定は不要になりました
# config.active_storage.resolve_model_to_route = :rails_storage_proxy
config.active_storage.resolve_model_to_route = :rails_storage_proxy
アップロードしたファイル(や加工したファイル)をダウンロードさせる際、デフォルトでは S3 の署名付きURLを発行してリダイレクトするようになっています。(リダイレクトモード)
<s>しかしながら、現在のところ R2 は署名付きURLによるインターネットからの直接読み込みはサポートされていない ため、アプリケーションサーバーでプロキシしてやる必要があります。(または取得用のCloudflare Workerを自分で用意するか)</s>
<s>:rails_storage_proxy
によって、アプリケーションサーバーがファイルデータを R2 からダウンロードして配信するようになります。(プロキシモード)</s>
追記:2022年9月に署名付きURLに対応したため、この対応は不要になりました。
サンプルコード
オープンβ時点では利用できない機能
署名付きURLによるダウンロード(リダイレクトモード)
現在のところR2は署名付きURLによる読み取りをサポートしていませんが、将来的にはサポートする予定のようです。
We’ll then focus on expanding R2 capabilities beyond the basic S3 API. In the near term, we’re focused on delivering:
- Pre-signed URL support, which delegates read and write access for a specific key to a token.
サポートされればプロキシモードを使わずに、リダイレクトモードで済みますね。
追記:対応しました!
2022年9月に署名付きURLに対応したため、利用できるようになりました。
リダイレクトモードが利用でき、Railsサーバーを通さずに配信できますね。
ダイレクトアップロード
Active Storage では簡単にストレージサービスへのダイレクトアップロードに対応することができます。
<%= form.file_field :attachment, direct_upload: true %>
しかしながら、現在のところR2は署名付きURLによる書き込みをサポートしていません。将来的にはサポートする予定のようです。
We’ll then focus on expanding R2 capabilities beyond the basic S3 API. In the near term, we’re focused on delivering:
- Pre-signed URL support, which delegates read and write access for a specific key to a token.
追記:対応しました!
2022年9月に署名付きURLに対応したため、利用できるようになりました。
まとめ
今回はActive StorageのファイルストレージサービスとしてCloudflare R2を使ってみました。
- Active Storage の動作に必要な最低限の S3 API に対応しているので利用できた
- ただ使うだけならS3と比べてR2側の設定はとても簡単だった
- Cloudflare Workers を使えばもっといろいろなことができそう
- WebP変換をして返すようにするとか
- Cloudflare Workers を使えばもっといろいろなことができそう
- Active Storage のリダイレクトモードは今のところ利用できず、プロキシモードが必要
- またはインターネット公開用の Cloudflare Workers を作るか
- ダイレクトアップロードは今のところ利用できない
Discussion