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

Delivering files through Cloudflare CDN using Cloud Storage for Firebase

firebase
cloudflare
cdn

投稿日: 2024/09/14

更新日: 2025/01/04

This article is a translation of the following article.

https://noh.ink/articles/w8llRm75TjX66qntnhT5

The blogging service noh uses Firebase, but images stored in Cloud Storage are delivered via Cloudflare CDN. This will explain the method.

The setup method is almost the same even if you are not using Firebase Cloud Storage.

Benefits of Using Cloudflare CDN

  • Cheap
    • Communication fees from GCP to Cloudflare are discounted (CDN Interconnect program).
    • Cloudflare CDN is available for free.
  • Relatively easy to set up
    • Using GCP's Cloud CDN probably requires load balancer configuration (I apologize if I am mistaken as I have never used it). I think Cloudflare is relatively easy because it automatically caches with just CNAME settings and such.

This time, we are using Cloud Storage for Firebase, but if you want to reduce costs, it might be worth considering using Cloudflare R2 instead.

Q&A

Is CDN configuration absolutely necessary?

A: Cloud Storage seems to behave like a CDN even without CDN settings (though the communication fees should remain the same). It won't be a problem for applications that don't have a lot of access. However, using a CDN can provide benefits in download speed and can reduce costs when there is a high volume of access.
Also, if there are requirements such as difficulty in changing the image URLs later, I believe it should be implemented early on. For example, this blog contains image URLs within the markdown, so changing the image URLs later can be quite challenging.

How will Firebase security rules be?

A: This section explains how to configure the settings to make all (or some) objects inside the bucket public. This allows them to be read from the URL, ignoring Firebase's security rules (however, writes can still be controlled by the security rules). It is advisable to create a separate bucket for public access.

I am using the default bucket for private use. Here I am using Firebase security rules to read.

Key Points of Configuration

  • Proof of ownership of the domain to be used is required.
  • The subdomain and bucket name used for distribution must be the same.

Setting Method

Determine the Subdomain to Use for the Distribution

We will decide on the subdomain to be used for distribution. The reason for deciding this in advance is that the subdomain used for distribution must be the same as the bucket name. In this article, we will use storage-noh-production.noh.ink.

This is written somewhere in the official documentation.

Proof of Domain Ownership for Subdomains

To create a subdomain bucket in Cloud Storage, it is necessary to prove domain ownership. If you attempt to create it in the Firebase console without doing this, it will fail (it will only display An error occurred while creating the bucket, so you won't know why it failed).

The requirements for the bucket name are described in the document.

The verification of ownership is done through the Search Console. Generally, it can be completed by just clicking the buttons, but if you encounter a 404 error or it fails, it might be a good idea to change to the following method.

  • In the instructions, change from “Cloudflare” to “any DNS provider” and proceed. The DNS settings will use the name noh.ink and the content will use the displayed TXT record. I have configured it here.
  • Set it up with the URL prefix. It seems that each subdomain needs to be configured separately.

Creating a Bucket

I will add a bucket. The important point is that the subdomain name will be the bucket name. Here it is set as storage-noh-staging.noh.ink. If the location is set to Tokyo, then it should be asia-northeast1.

I am making all objects in the created bucket public. By making all objects in the bucket public, access becomes possible, ignoring Firebase security rules. Please be careful not to add objects that you do not want to make public in the relevant bucket.

I am making all objects in the bucket public, but I also think it would be fine to only make part of the bucket public.

Just set it up according to the following document.

Please be careful to set it up so that unintended files are not made public.

DNS Settings

Add a CNAME to DNS.

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

The document instructs to set c.storage.googleapis.com., but the final dot disappeared when saved.

Confirmation

I will upload an appropriate file from the Firebase console screen.

You can access the uploaded file via the URL.
The URL is like https://${storageBucketName}/${filePath}, and the URL of the image below is https://storage-noh-production.noh.ink/public/users/2goNuJNOwlWdiNM2FK20SARNFYq2/markdownImages/FJd0PZjcffz6wGdQhyUf/origin.webp.

Let's open the image in a new tab and take a look at the Response headers. You can confirm the parameters related to the Cloudflare CDN.

After reloading a few times, it was confirmed that the cf-cache-status:HIT indicates that it is being delivered from the CDN cache.

Bonus

About Using an Emulator

The URL to access will look like http://localhost:9199/storage-noh-production.noh.ink/${path}. In practice, I don't think you will connect from the development environment to the production environment, so I believe the part storage-noh-production.noh.ink will be storage-noh-development.noh.ink.

Reference