Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】🚀 Speed Up Your Images: Complete Guide to Cloudflare CDN + Amazon S3

2025年09月21日に「Dev.to」が公開したITニュース「🚀 Speed Up Your Images: Complete Guide to Cloudflare CDN + Amazon S3」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

S3からの画像読み込みが遅くAWS費用が高い問題を解決するため、Cloudflare CDNをS3の前に設定する方法を解説。S3バケット設定、CloudflareのDNS、キャッシュルール、Cloud Connector設定を通じて、画像を世界中のユーザーへ高速に配信し、コスト削減とパフォーマンス向上を実現する。Cloudflare無料プランでも対応可能だ。

ITニュース解説

Sushil Subedi氏の記事では、ウェブサイトにおける画像の読み込み速度の向上と、それにかかるコストの削減という、多くのシステムエンジニアが直面する課題に対する実践的な解決策が示されている。具体的には、Amazon S3に保存された画像をCloudflareのCDN(コンテンツデリバリーネットワーク)を通して配信することで、これらの問題を劇的に改善できるという内容だ。システムエンジニアを目指す初心者でも理解できるように、その仕組みと具体的な手順を解説する。

まず、この仕組みがなぜ効果的なのかを理解することが重要だ。一般的なウェブアプリケーションでは、画像のような静的コンテンツをAmazon S3のようなオブジェクトストレージサービスに保存し、そこから直接ユーザーに配信することが多い。しかし、この方法にはいくつかの課題がある。例えば、アメリカ東部にS3バケットがあるとして、東京のユーザーが画像にアクセスした場合、データはアメリカから東京まで長い距離を移動することになるため、読み込みに時間がかかる。また、同じユーザーがページを更新するたびにS3へのリクエストが発生し、そのたびにデータ転送量に応じた費用がAWSに請求されることになる。

ここでCloudflare CDNが解決策となる。Cloudflareは世界中に「エッジロケーション」と呼ばれるデータセンターを展開しており、ユーザーがウェブサイトにアクセスすると、最も近いエッジロケーションからコンテンツを配信する仕組みだ。S3の前にCloudflareを配置すると、一度S3から取得された画像はCloudflareのエッジロケーションに一時的に保存(キャッシュ)される。これにより、東京のユーザーはアメリカのS3バケットからではなく、東京のエッジロケーションから画像を受け取れるようになるため、読み込み速度が大幅に向上する。さらに、一度キャッシュされた画像は、その後の同じ画像へのリクエストに対してはS3にアクセスすることなくCloudflareから直接配信されるため、S3のデータ転送量も削減され、AWS費用を抑えることができる。つまり、パフォーマンス向上とコスト削減を同時に実現できる「無料のパフォーマンスマジック」と表現されている。

この設定を行うために必要なものは、Amazon Web Services(AWS)のアカウントとS3バケット、そしてCloudflareで管理されているドメインだ。Cloudflareは無料プランでもこの仕組みを利用できるため、手軽に導入できる。

具体的な設定手順は以下の通りだ。

最初のステップはS3バケットの準備だ。新しいS3バケットを作成するか、既存のバケットを使用する。バケット名は任意で設定する。ここで特に重要なのは、「Block All Public Access(すべてのパブリックアクセスをブロック)」の設定を解除することだ。これは、S3バケット内の画像をウェブからアクセスできるようにするために必要な作業で、この設定を有効にしたままでは、後続のステップで画像を公開できない。また、バケットを作成する際には、主要なユーザーがいる地域、または自分に最も近い地域を選択すると良い。これにより、S3からCloudflareへの初回データ転送を少しでも速くすることができる。

次に、S3バケットに「バケットポリシー」を設定する。これはS3の厄介な点の一つで、パブリックアクセスブロックを解除しただけでは画像は外部から読み取れない。JSON形式のポリシーをバケットの「Permissions(アクセス権限)」セクションに追加する必要がある。このポリシーは、「AllowPublicRead」という識別子を持つステートメントで、誰でも("Principal": "")「s3:GetObject」というアクション(オブジェクトの取得)を、指定されたS3バケット内のすべてのリソース("Resource": "arn:aws:s3:::my-images-bucket/")に対して実行できる、という意味だ。ここで「my-images-bucket」の部分を自分のS3バケット名に正確に置き換える必要がある。このポリシーを保存したら、テスト用の画像をS3にアップロードし、S3が提供する直リンクURLで画像にアクセスできるか必ず確認することが重要だ。この確認を怠ると、後続のステップで問題が発生した際に原因の特定が難しくなる。

S3バケットの準備が整ったら、次はCloudflareでの設定だ。Cloudflareのダッシュボードにログインし、「DNS」セクションへ移動して「CNAMEレコード」を追加する。CNAMEは「Canonical Name(正規名)」の略で、あるドメイン名が別のドメイン名のエイリアス(別名)であることを示すレコードだ。例えば、「images」という名前を設定し、そのターゲットを「my-images-bucket.s3.amazonaws.com」のように自分のS3バケットのホスト名に指定する。この設定により、ユーザーは「https://images.yourdomain.com/path/to/image.jpg」のような、より分かりやすいURLで画像にアクセスできるようになる。このCNAMEレコードの横にある雲のアイコンが「オレンジ色」(プロキシモードが有効)になっていることを確認することが極めて重要だ。オレンジ色の雲は、CloudflareのCDNが有効になり、トラフィックがCloudflareを介して処理されることを意味する。もし灰色の場合、Cloudflareは単なるDNSプロバイダーとして機能し、CDNの恩恵を受けられない。

この段階で、画像はCloudflareのCNAME経由でアクセスできるようになったが、まだキャッシュの恩恵を十分に受けているわけではない。次に「キャッシュルール」を設定する。Cloudflareの「Rules(ルール)」セクションにある「Cache Rules(キャッシュルール)」で新しいルールを作成する。「Cache everything(すべてをキャッシュ)」というテンプレートを選択し、「Edge Cache TTL(エッジキャッシュ存続期間)」を1ヶ月、「Browser Cache TTL(ブラウザキャッシュ存続期間)」を7日に設定することが推奨されている。TTLとは「Time To Live」の略で、コンテンツがキャッシュとして保存される期間を示す。画像は頻繁に更新されないため、長めに設定することでキャッシュヒット率が高まり、パフォーマンスが向上する。このルールの対象URLパターンは、「images.yourdomain.com/*」のように設定し、Cloudflare経由で配信されるすべての画像がキャッシュの対象となるようにする。

次に、この設定の「隠し味」とも言える「Cloud Connector(クラウドコネクタ)」を設定する。著者は当初、この設定を重要視していなかったが、S3とCloudflareを連携させる上で非常に重要な役割を果たすことが判明したと述べている。Cloud Connectorは、S3が要求する「Hostヘッダー」を修正し、リクエストがS3バケットに正しくルーティングされるようにする役割を自動的に担う。S3はHostヘッダーの扱いが厳格なため、Cloud Connectorなしでは正しく動作しない場合がある。Cloudflareの無料プランでも10個のコネクタが利用でき、通常は十分な数だ。「Rules」セクションから「Cloud Connector」を選択し、「AWS S3」を選択して、S3バケットの情報を入力する。ここでの注意点は、ホスト名パターンに「images.yourdomain.com/*」のようなワイルドカードを使用することだ。これにより、異なるパスにある様々な画像が正しくS3バケットにルーティングされる。バケット名にタイプミスがないか、正確に確認することが重要だ。著者の経験でも、タイプミスが原因で20分間デバッグに費やしたという。

ウェブアプリケーションがRails(Ruby on Rails)を使用している場合、追加の工夫が必要になる。ActiveStorageのようなRailsの標準機能で画像を扱っている場合、通常は「署名付きURL」が生成される。しかし、この署名付きURLはクエリパラメータを含んでおり、CDNでのキャッシュと相性が悪い。そのため、記事ではカスタムのヘルパーメソッドを作成し、S3ではなくCloudflareのドメインをベースとした画像URLを生成する方法が紹介されている。これにより、開発環境ではS3直リンクを使い、本番環境ではCloudflare CDN経由のURLを使うといった切り替えも容易になる。

著者がこの設定を通じて得た教訓はいくつかある。まず、キャッシュルール(キャッシュヘッダー)が適切に設定されていないと、Cloudflareが画像をキャッシュしてくれないため、パフォーマンスの恩恵を受けられないということ。次に、CloudflareがS3から画像を初回取得する際には、やはり多少の遅延が発生するが、二回目以降のリクエストは劇的に高速になるという点だ。そして、ActiveStorageなどの署名付きURLがCDNと相性が悪いため、専用のヘルパーが必要になるという実用的な知見も挙げられている。また、デバッグ時にはcurl -I https://images.yourdomain.com/some-image.jpgのようなコマンドを使って、HTTPレスポンスヘッダーにcf-cache-status: HITが含まれているかを確認することが有効だ。これにより、画像がCloudflareによって正常にキャッシュされているかを確認できる。

これらの設定を適用した結果、国際的なユーザー向けの画像の読み込み時間は、以前の500ミリ秒から20〜30ミリ秒へと劇的に短縮されたという。この設定には著者のデバッグ時間を含めても2〜3時間しかかからず、その手間に見合う、いやそれ以上の効果が得られたと結論付けている。Cloudflareの無料プランで利用できるため、コストもほとんどかからず、ユーザー体験の向上とAWS費用の削減の両方を実現できる。現在S3から直接画像を配信しているウェブサービスであれば、この設定を検討する価値は十分にある。これは、システムエンジニアを目指す上で、パフォーマンス最適化とコスト管理の重要性を理解する良い事例となるだろう。

関連コンテンツ

関連IT用語