はじめに

ウェブサイトが読み込む必要のある画像やアセットのせいで遅くなったことはありませんか?あるいは、サイトが成長するにつれてこれらのファイルを管理するのに苦労したことは?実は、ウェブサーバーから直接画像を保存・配信するのは便利に思えるかもしれませんが、すぐにボトルネックに変わってしまうことがあります。

そこでAWSの出番です。S3を使ったストレージやCloudFrontのような強力なCDNを利用すれば、世界中どこにいてもユーザーに画像やアセットを瞬時に管理、最適化、配信できます。

このガイドでは、ウェブアプリサーバーに画像を保存するのがなぜ良くないのか、サービスを分けることがどれほどゲームチェンジャーであるか、そしてAWSのツールがどれほどあなたの生活を楽にしてくれるかを説明します。それでは、始めましょう!

ウェブサーバーに画像を保存するのがなぜ良くないのか

サーバー負荷の増加

ウェブサーバーがアプリを実行し、画像を配信する両方を担当すると、すぐに負荷がかかります。画像リクエストが増えるごとに追加の作業が発生し、すべてが遅くなります。サイトに多くのトラフィックがある場合、サーバーは追いつけなくなり、遅延やクラッシュを引き起こす可能性があります。買い物の荷物を全部持って走ろうとするようなものです—効率的ではありません!

スケーラビリティの制限

サイトが成長するにつれて、画像やユーザーの数も増えます。単一のウェブサーバーは、限界に達するまでしか処理できません。スケールアップするには、より大きなサーバーにお金をかけるか、すべてを移行する手間がかかります。AWS S3のようなクラウドストレージを使えば、スペースが不足する心配はありません—それはあなたと共に成長します。

パフォーマンスボトルネックのリスク

大きな画像ファイルは、特にアプリの機能を処理している同じサーバーから配信している場合、サイトを非常に遅くする可能性があります。サイトの一部が遅いと、他のすべてが影響を受け、ユーザーは長い読み込み時間に不満を感じます。片側通行の道路での渋滞のようなものです—すべてが滞ります。

セキュリティの懸念

ウェブサーバーから画像を配信すると、不必要なリスクにさらされる可能性があります。ハッカーが脆弱性を悪用して機密情報にアクセスするか、他のサイトがあなたの画像をホットリンクして帯域幅を盗むかもしれません。適切な保護策がないと、サーバーファイルパスを誤って公開してしまうことになります。これは、前のドアを開けっぱなしにしているようなものです。

CDNを使用する理由

遅いウェブサイトにイライラしたことがあるなら、CDN (コンテンツ配信ネットワーク)がどれほどのゲームチェンジャーであるか理解できるでしょう。CDNは、世界中に広がるミニ倉庫のネットワークのようなもので、それぞれがあなたのサイトの画像やアセットのコピーを保存しています。すべてのユーザーがメインサーバーからコンテンツが届くのを待つ必要がなく、CDNが最寄りの倉庫から配信するため、すべてがより速く、スムーズになります。

CDNはデータをグローバルエッジサーバーに配信することでコンテンツ配信を加速します。
CDNはデータをグローバルエッジサーバーに配信することでコンテンツ配信を加速します。

CDNを使用して画像とアセットを配信する理由は次のとおりです:

どこでもユーザーのためのより速い読み込み時間

メインサーバーがニューヨークにあるとしましょう。しかし、東京の誰かがあなたのサイトを訪れた場合、CDNがなければ、そのリクエストは世界の半分を旅しなければなりません。時間がかかります。CDNを使えば、東京の近くのサーバーがコンテンツを配信し、移動時間を短縮し、サイトの読み込みが瞬時に行われます。読み込み時間が短くなると、ユーザーはより満足し、長く滞在してくれます。

レイテンシの低減とユーザー体験の向上

レイテンシとは、ユーザーが何かをクリックしてからコンテンツが実際に表示されるまでの煩わしい遅延のことです。ユーザーがサーバーから遠いほど、レイテンシは高くなります。CDNは、画像やアセットをユーザーの近くに持ってくることでこれを解決し、遅延を減らし、すべてを瞬時に感じさせます。ロンドンのソファに座っている人でも、シドニーのカフェにいる人でも、同じシームレスな体験を楽しめます。

メインサーバーからのトラフィックのオフロード

ウェブサーバーをレストランの忙しいシェフと考えてみてください。CDNがなければ、シェフはすべてを処理しなければなりません:料理、配膳、さらには遠くの顧客への配達まで。CDNを使えば、シェフ(サーバー)は料理(アプリの実行)に集中でき、CDNが配達(画像やアセットの配信)を担当します。これにより、メインサーバーからのトラフィックが大幅にオフロードされ、過負荷を防ぎ、トラフィックの急増時でもサイトがスムーズに動作し続けます。

S3とCloudFrontとは?

S3 (Simple Storage Service)

S3は、Amazonの安全でスケーラブル、かつ非常に信頼性の高いクラウドストレージソリューションです。画像、動画、その他のアセットなど、あらゆる種類のデータを保存するために設計されており、ウェブサイトやアプリケーションに最適な選択肢です。小さな個人ブログをホストしている場合でも、大規模なeコマースプラットフォームを運営している場合でも、S3はストレージニーズを楽に処理できます。さらに、柔軟なストレージティアを提供しているので、使用した分だけ支払えば大丈夫です。

CloudFront

CloudFrontは、Amazonのコンテンツ配信ネットワーク(CDN)サービスで、迅速かつ安全なコンテンツ配信を実現します。これは、世界中にあるエッジサーバーに画像やアセットをキャッシュすることで機能し、ユーザーは最寄りのサーバーから迅速にアクセスできます。S3と組み合わせることで、CloudFrontは保存されたアセットをシームレスに取得し、最小限のレイテンシで配信することで配信プロセスを最適化します。S3とCloudFrontを組み合わせることで、ウェブサイトコンテンツの管理と配信において強力で効率的、かつスケーラブルなソリューションを提供します。

S3とCloudFrontの使用コスト

AWSの最も良い点の一つは、使用した分だけ支払えば良いことです。以下に簡単な内訳を示します:

  • S3のコスト:
    • ストレージコスト: 保存されたデータのGBごとに支払い、ストレージティア(例:Standard、Infrequent Access、Glacier)によって異なる料金が適用されます。
    • リクエストコスト: バケットへのPUT、GET、その他のリクエストに対して料金が発生します。
    • データ転送: S3からインターネットへのデータ転送には追加料金が発生します。
  • CloudFrontのコスト:
    • データ転送: エッジロケーションを通じてユーザーに配信されるデータの量に対して支払います。
    • リクエスト: CloudFrontに対して行われたHTTP/HTTPSリクエストに料金が発生します。
    • 地域価格設定: ユーザーの所在地によってコストが異なる場合があります。

詳細については、Amazon S3の価格 と Amazon CloudFrontの価格 を参照してください。

例: S3とCloudFrontの使用コスト

小さなeコマースウェブサイトを運営していて、商品画像を保存・配信する必要があるとしましょう。以下は簡略化したコスト内訳です:

シナリオの詳細

  • ストレージ: S3に保存された画像100GB(Standard Tier)。
  • リクエスト: S3へのGETリクエスト50,000件とPUTリクエスト10,000件。
  • データ転送: CloudFrontへのデータ転送100GB。
  • CloudFrontデータ配信: CDNを通じてエンドユーザーに配信されるデータ100GB。

S3のコスト

  1. ストレージコスト:
  • S3 Standard Storageの100GB = $2.30(約$0.023/GB)。
  1. リクエストコスト:
  • 50,000 GETリクエスト = $0.04(約$0.0004/1,000リクエスト)。
  • 10,000 PUTリクエスト = $0.05(約$0.005/1,000リクエスト)。
  1. データ転送コスト(CloudFrontへの):
  • 100GB = $0(S3からCloudFrontへのデータ転送は無料です)。

合計S3コスト: $2.39/月

CloudFrontのコスト

  1. データ転送コスト(CloudFrontからユーザーへの):
  • エンドユーザーに配信される100GB = $8.50(最初の10TBあたり約$0.085/GB)。
  1. リクエストコスト:
  • 50,000 HTTP/HTTPSリクエスト = $0.10(約$0.002/1,000リクエスト)。

合計CloudFrontコスト: $8.60/月

合計金額

月額合計コスト: $2.39 + $8.60 = $10.99

AWS S3とCloudFrontを設定して画像とアセットをホストする

このガイドでは、AWS S3とCloudFrontを設定して、カスタムサブドメインで画像を効率的に配信する方法を説明します。

この設定により、以下のことが保証されます:

  • 許可されたドメインからのリクエスト(例:yoursite.com)がアセットにアクセスできます。
  • リファラーヘッダーなしのリクエスト(例:S3 URLへの直接アクセス)はブロックされます。
  • 未認証のウェブサイトからのリクエスト(ホットリンク)は拒否されます。
  1. AWS Certificate Manager (ACM)でSSL証明書を作成する

CloudFrontはカスタムドメインでHTTPSを使用するために有効なSSL証明書が必要なので、最初のステップはSSL証明書を生成することです。

  • AWS Certificate Manager (ACM)に移動します。
  • <b>証明書のリクエスト</b>をクリックします。
  • <b>パブリック証明書のリクエスト</b>を選択します。
  • <b>サブドメインを入力します</b>(images.yoursite.com)、ワイルドカード証明書が必要な場合は*.yoursite.comも追加します。
  • <b>DNS検証</b>を選択します(推奨)。
  • 送信後、AWSはCNAMEレコードを提供します。これをDNSプロバイダー(例:Route 53、Cloudflare、GoDaddy)に追加する必要があります
  • DNSレコードが検証されると、証明書が発行されます。
AWS Certificate Manager: サブドメイン用のSSL証明書が正常に発行されました
AWS Certificate Manager: サブドメイン用のSSL証明書が正常に発行されました
  1. 画像配信用のサブドメインを作成する

SSL証明書が準備できたので、画像を配信するためのサブドメイン(images.yoursite.com)を設定します。

  • DNSプロバイダー(Route 53、Cloudflareなど)に移動します。
  • CNAMEレコードを作成します:
    • レコード名: images
    • タイプ: CNAME
    • 値: <your-cloudfront-distribution-id>.cloudfront.net
  1. CloudFrontディストリビューションを作成する

次に、CloudFrontを設定してS3から画像を配信します。

  • AWS CloudFrontに移動 → ディストリビューションを作成します。
  • オリジンの下で、次のように設定します:
    • オリジンドメイン名: S3バケットを選択します。
    • オリジンアクセス: レガシーアクセスIDを選択 → オリジンアクセスID(OAI)を作成します。
    • バケットポリシー: バケットポリシーを手動で更新しますを選択します。
  • 動作を設定
    • オブジェクトを自動的に圧縮: ✅ はい
    • ビューワープロトコルポリシー: HTTPをHTTPSにリダイレクト
    • 許可されたHTTPメソッド: GET, HEAD
    • ビューワーアクセスを制限: ❌ いいえ(サイン付きURLが必要な場合を除く)
  • キャッシュとオリジンリクエスト設定
    • キャッシュポリシー: ✅ CachingOptimized
    • オリジンリクエストポリシー: ✅ UserAgentRefererHeaders(RefererをS3に渡す)
  • SSL証明書を割り当てる
    • <b>設定</b>の下で、<b>カスタムSSL証明書</b>を選択します。
    • <b>AWS Certificate Managerで作成した証明書を選択します</b>。
  • <b>ディストリビューションを作成</b>をクリックします。
CloudFront: オリジン設定
CloudFront: オリジン設定
CloudFront: 動作設定
CloudFront: 動作設定
  1. S3バケットの権限を設定する

デフォルトでは、S3バケットはプライベートです。CloudFrontがアクセスできるようにする必要があります。

  • S3に移動 → バケットを選択します。
  • 権限 → ✅ すべてのパブリックアクセスをブロックを有効にします(CloudFrontがアクセスを処理するため)。
  • バケットポリシーを更新します:

以下のように、<bucket name>と<cloud front oai>を実際の値に置き換えます:


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAccessFromSubdomains",
            "Effect": "Allow",
            "Principal": {
                "AWS": "<cloud front oai>"
            },
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::<bucket name>/images/*",
                "arn:aws:s3:::<bucket name>/assets/*"
            ],
            "Condition": {
                "StringLike": {
                    "aws:Referer": [
                        "http://*.yoursite.com/*",
                        "https://*.yoursite.com/*",
                        "http://yoursite.com/*",
                        "https://yoursite.com/*"
                    ]
                }
            }
        }
    ]
}
  1. 最終ステップ
  • CloudFrontをデプロイします:CloudFrontディストリビューションのデプロイが完了するのを待ちます。
  • 画像の読み込みをテスト:
    • 画像にアクセスしてみてください:https://images.yoursite.com/path/to/image.jpg
  • もし403 Forbiddenが表示されたら、以下を確認してください:
    • <b>CloudFront OAI</b>が正しく割り当てられています。
    • <b>S3バケットポリシー</b>にOAI ARNが含まれています。
    • <b>リファラーヘッダー</b>が転送されています。

✅ これで、AWS S3とCloudFrontを使った完全に設定された、最適化された、安全な画像配信セットアップが完成しました!🚀

結論

これで完了です!AWS S3とCloudFrontが連携することで、プロのように画像を迅速かつ安全に配信する方法を構築しました。ウェブサーバーが遅くなることも、遅い読み込み時間に悩まされることもありません—CloudFrontが重い作業を処理し、S3がすべてを整理して安全に保ちます。リファラーヘッダーを転送し、直接S3へのアクセスをブロックすることで、ホットリンクや不要なトラフィックを防ぎました。これで画像は瞬時に読み込まれ、保護され、スムーズにスケールします。シンプルで効率的、そして長持ちするように作られています!🚀