Noh | エンジニア向け情報共有コミュニティ
Signup / Login

Cloud Storage for Firebase でファイルをCloudflare CDN経由で配信する

firebase
cloudflare
cdn

投稿日: 2024/09/14

更新日: 2024/09/21

ブログ投稿サービスであるnohではFirebaseを使っているが、Cloud Storageに保存されている画像はCloudflare CDN経由で配信しています。その方法の解説をします。

Firebaseを使っていないCloud Storageでも設定方法はほぼ同じです。

Cloudflare CDNを使うメリット

  • 安い
  • 比較的設定が簡単
    • GCPのCloud CDNを使うには多分ロードバランサの設定が必須(使ったことないので間違っていたらすいません)。CloudflareはCNAMEの設定などだけで勝手にキャッシュしてくれて比較的簡単だと思います。

今回はCloud Storage for Firebase を使っていますが、もっと安くしたいのであれば、代わりにCloudflare R2の使用を検討してもいいかもしれません。

Q&A

CDNの設定は必ず必要か

A: Cloud StorageはCDNの設定なしでもCDNのような挙動をしてくれるようです(とはいっても通信料金はそのままのはず)。大量のアクセスが無いアプリケーションではなくても困りません。しかし、CDNを経由させることでダウンロード速度の恩恵があったり、大量のアクセスがあったときに料金を安くできます。
また、後で画像のURLを変更しにくいなどの要件があれば早い段階で導入すべきだと思います。例えばこのブログではマークダウン内に画像URLが入っているので、後から画像URLを変更するのはかなり大変です。

Firebaseのセキュリティルールはどうなるか

A: 今回、バケット内部のオブジェクトすべて(または一部)を公開する設定を行う方法を解説します。これによってFirebaseのセキュリティルールを無視してURLからreadできるようになります(ただし、writeについてはセキュリティルールで制御できます)。公開用のバケットは別のバケットを作成するといいです。

私はデフォルトのバケットを非公開用にしています。こちらはFirebaseのセキュリティルールを使ってreadしています。

設定のポイント

  • 使用するドメインの所有権の証明が必要です。
  • 配信に使用するサブドメインとバケット名は同じにする必要があります。

設定方法

配信に使用するサブドメインを決定

配信に使用するサブドメインを決定します。先に決めておく理由は、配信に使用するサブドメインとバケット名は同じにする必要があるからです。この記事ではstorage-noh-production.noh.inkとします。

公式ドキュメントにはこのあたりに書かれています。

https://cloud.google.com/storage/docs/request-endpoints?hl=ja#cname

サブドメインのドメイン所有権の証明

Cloud Storageにサブドメインのバケットを作るためには、ドメイン所有権の証明を行う必要があります。これをせずにFirebaseのコンソール画面で作成を行うと失敗します(バケットの作成中にエラーが発生しましたとしか表示されないので、なんで失敗したかわかりませんでした)。

バケット名の要件のドキュメントに記載されています。

所有権の照明はSerch consoleから行います。基本的にはボタンをポチポチしていけば完了しますが、404が出たり失敗する場合は以下の方法に変更するといいかもしれません。

  • 手順のとこで、「Cloudflare」から「任意のDNSプロバイダ」に変更して進める。DNSの設定は名前をnoh.ink、コンテンツは表示されたTXT レコードを使います。私はこちらで設定しました。
  • URL プレフィックスで設定する。サブドメインごとに設定が必要そうです。

バケットの作成

バケットを追加します。注意点はサブドメイン名をバケット名にします。ここではstorage-noh-staging.noh.inkとしました。
ロケーションは東京にするならasia-northeast1です。

私は、作成したバケット内のオブジェクトすべてを公開しています。バケット内のすべてのオブジェクトを公開すると、Firebaseのセキュリティルールも無視してアクセス可能になります。該当バケット内に公開したくないオブジェクトを追加しないように注意してください。

私はバケット内のオブジェクトすべてを公開していますが、バケットの一部だけ公開することもできるのでそちらでもいいと思います。

以下のドキュメント通りに設定するだけです。

意図しないファイルが公開されないように、注意して設定してください。

DNSの設定

DNSにCNAMEを追加します。

typenamedata
CNAMEstorage-noh-productionc.storage.googleapis.com

ドキュメントにはc.storage.googleapis.com.を設定するように書かれていますが、最後のドットは保存すると消えました。

確認

適当なファイルをFirebase console画面からアップロードします。

アップロードしたファイルにURL経由でアクセスします。
URLはhttps://${storageBucketName}/${filePath}のような感じで、以下の画像のURLはhttps://storage-noh-production.noh.ink/public/users/2goNuJNOwlWdiNM2FK20SARNFYq2/markdownImages/FJd0PZjcffz6wGdQhyUf/origin.webpです。

画像を新しいタブで開いてResponse headersを見てみます。Cloudflare CDN関連のパラメータが確認できます。

何度か再読み込みするとcf-cache-status:HITとなり、CDNのキャッシュから配信されていることが確認できました。

おまけ

Emulatorを使っている場合について

アクセスするURLはhttp://localhost:9199/storage-noh-production.noh.ink/${path}のようになります。実際には開発環境から本番環境につなぐことはないと思うので、storage-noh-production.noh.inkの部分はstorage-noh-development.noh.inkになると思います。

参考

yosi

Noh を作ってるエンジニア。