サーバーレスで簡単!S3とLambdaを使った Reactアプリの構築方法

※当サイトは、アフィリエイト広告を利用しています。

くれとむ

ねえ、チーズくん、AWSを使ってReactアプリを簡単にホストする方法知ってる?

チーズくん

もちろん!AWSのS3とLambdaを使えばいいんだよ!

くれとむ

それ、それ!今回はAWS上で実際にWebアプリをホストしてみよう!

今回は、AWS の強力なサービスである S3 と Lambda を活用して、React アプリをホストする方法をご紹介します。
この記事では、環境準備からホスティングまでをステップバイステップで解説し、独自ドメインの設定や HTTPS の有効化までカバーします。
初心者でもわかりやすく実践できる内容なので、ぜひ最後までご覧ください!

本記事で使用するコードのgithub

このプロジェクトの完全なコードはGitHubリポジトリで公開しています。
以下のリンクからダウンロードしてください。
https://github.com/my-repo-441/aws-s3-lambda-example

環境準備

Viteを使ったReactアプリの作成

まず、Node.jsをインストールして、正しいバージョンが導入されていることを確認します。
私の環境は以下の通りです。

% node -v
v22.10.0

その後、Viteを使ってReactアプリを以下の手順で作成します。

手順:Reactアプリの作成
  1. Viteプロジェクトを作成します。
% npm create vite@latest my-app -- --template react
  1. 作成されたディレクトリに移動して依存関係をインストールする
% cd my-app
% npm install
  1. 開発サーバーを開始します。
npm run dev

ブラウザで http://localhost:5173 を開き、初期のReactアプリが動作していることを確認します。

Reactアプリの修正

以下のコードをsrc/App.jsxに記述し、 Lambdaとの連携機能を追加します。
これにより、S3でホストしたアプリから、バックエンドのAWS Lambdaに処理を引き渡します。

https://<API_GATEWAY_URL>は後述するLambda関数のデプロイ後に作成されるAPI GatewayのエンドポイントURLを記載します。

import React, { useState } from 'react';
import './App.css';

function App() {
  const [message, setMessage] = useState('Click the button to fetch data.');

  const fetchData = async () => {
    setMessage('Fetching data...');
    try {
      const response = await fetch('https://<API_GATEWAY_URL>');
      const data = await response.json();
      setMessage(`Response: ${data.message}`);
    } catch (error) {
      setMessage('Error fetching data.');
      console.error(error);
    }
  };

  return (
    <div className="App">
      <header className="App-header">
        <h1>Vite + React + Lambda Example</h1>
        <button onClick={fetchData}>Fetch Data</button>
        <p>{message}</p>
      </header>
    </div>
  );
}

export default App;

以下のスタイルを src/App.css に記述して、画面の見た目を整えます。

.App {
  text-align: center;
}

.App-header {
  background-color: #282c34;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: calc(10px + 2vmin);
  color: white;
}

button {
  padding: 10px 20px;
  font-size: 16px;
  margin-top: 20px;
  cursor: pointer;
  background-color: #61dafb;
  border: none;
  border-radius: 5px;
  transition: background-color 0.3s ease;
}

button:hover {
  background-color: #21a1f1;
}

p {
  margin-top: 20px;
  font-size: 18px;
}

修正後の画面は以下のようになっています。


次に、ReactアプリをS3でホストできる静的ファイルに変換します。

% npm run build

これにより、dist/ディレクトリが作成されます。この中に公開用のHTML、CSS、JavaScriptファイルが含まれています。

くれとむ

これでReactのサンプルアプリができたね!

チーズくん

うん、次はS3にデプロイだね!

S3バケットの作成&設定

S3バケットの作成

AWSマネジメントコンソールにログインし、S3のサービスを選択します。
S3バケットを作成します。

  • バケットの設定:
    • バケット名: 一意の名前を設定(例: my-app-s3-lambda-hosting)。
    • リージョン: 希望するリージョンを選択。
    • 「パブリックアクセスをブロック」: チェックを外す(後で公開設定を変更)。
    • 他の設定はデフォルトでOK。
  • バケットを作成をクリック。

ReactアプリをS3にアップロード

  • ビルドしたファイルをアップロード
    • AWSコンソールで作成したバケットを選択。
    • 「アップロード」ボタンをクリックし、dist/フォルダ内のすべてのファイルを選択してアップロード。
Screenshot

S3バケットの設定

アプリをホストするために、作成したバケットのプロパティを選択し、「静的ウェブサイトホスティング」の編集ボタンを押下します。
静的ウェブサイトホスティング」を有効にします。
インデックスドキュメントには「index.html」を指定します。

Screenshot


また、バケットポリシーも以下の形式で設定してください。
your-backet-nameには、自身で作成したS3バケット名を入力します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::your-backet-name/*"
        }
    ]
}

このバケットポリシーは、作成したバケット内のすべてのオブジェクトを、誰でも読み取れる(公開アクセス可能)ように設定しています。

Screenshot
チーズくん

この設定がないと、アプリが外部から見えないんだよね?

くれとむ

その通り!セキュリティとアクセス許可は非常に大事だよ!

S3でホストしたWebアプリへのアクセス

くれとむ

これでS3バケットを使った静的ウェブサイトのホスティングが完了したよ。
実際にURLにアクセスして動作を確認してみよう!

S3バケットのプロパティの「静的ウェブサイトホスティング」に記載されている「バケットウェブサイトエンドポイント」のURLにアクセスします。

Screenshot

Webアプリにアクセスできれば成功です。

Lambda関数へのデプロイ

バックエンドの処理をLambda関数にデプロイします。
デプロイには、Serverless Frameworkを用います。Serverless Frameworkは、開発者がAWS Lambdaや他のサーバーレスアーキテクチャを迅速かつ容易に構築・デプロイするための強力なツールです。

インストール手順および基本的な使い方については、以下の記事に記載しているので、必要に応じてご参照ください。

Lambda関数の作成

以下のコマンドでlambda関数用のディレクトリと空ファイルを作成します。

% mkdir lambda
% cd lambda
% touch lambda_function.py
% touch serverless.yaml

lambda_function.pyを以下の内容で更新します。

import json

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'application/json'
        },
        'body': json.dumps({'message': 'Hello from Lambda!'})
    }

Serverless Frameworkでは、serverless.yamlでデプロイするLambda関数の設定を記載します。今回の検証では、以下のように記載します。
your-organizationは、自身のServerless Frameworkの組織名を入力します。
your-s3-endpoint-urlは、自身のS3バケットのエンドポイントURLを入力します。

org: your-organization
app: my-app-s3-lambda-hosting
service: my-app-s3-lambda-hosting

provider:
  name: aws
  runtime: python3.12
  region: ap-northeast-1
  httpApi:
    cors:
      allowedOrigins:
        - your-s3-endpoint-url
      allowedMethods:
        - GET
      allowedHeaders:
        - Content-Type
        - Authorization
        - x-requested-with
        - origin
        - accept

  environment:
    PYTHONPATH: "/var/task/src:/opt/python"

functions:
  lambda_api:
    handler: lambda_function.lambda_handler
    timeout: 30
    events:
      - httpApi:
          path: /lambda
          method: get

Lambdaに対してデプロイ

以下のコマンドでLambdaに対してデプロイします。

% serverless deploy

デプロイが成功すると、以下のようにLambdaコンソール画面から関数が作成(更新)されていることを確認できます。

API GatewayのCORSの設定

ReactアプリからAPIを呼び出せるようにするため、API GatewayでCORS設定を有効化します。
これにより、異なるオリジン間のリクエストが許可され、Lambda関数を安全に呼び出すことができます。 (今回の場合は、S3バケットから、Lambdaに対するリクエスト許可)
ちなみにCORS設定が正常に行えていない場合は、以下のようなエラーが出ます。

CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource

以下は、手動でAPI GatewayのCORS設定を行う手順です。

手順
  1. LambdaにGETリクエストを送るためのAPI Gatewayを作成します。
  2. 作成したAPI GatewayでCORS設定を開きます。
  3. 許可するオリジン、ヘッダー、メソッドを追加します。
    (Access-Control-Allow-OriginにはS3バケットのエンドポイントURLを記載します。)

なお、serverless.yamlでデプロイした場合は、自動でAPI Gatewayが作成されています。念のため、API Gatewayの作成およびCORSが完了していることを確認しましょう。

S3とLambdaによるReactアプリの動作確認

S3とLambdaによるReactアプリの動作を確認します。
構成図は以下の通りです。

API GatewayのエンドポイントURLを確認し、フロントエンドのApp.jsxに反映します。

API GatewayのエンドポイントURLの確認方法
  • Serverless Frameworkでデプロイを実行すると、デプロイ完了後のログにエンドポイントURLが表示されます。
% serverless deploy

#出力例
Service Information
service: post-pilot-s3-hosting
stage: dev
region: ap-northeast-1
stack: post-pilot-s3-hosting-dev
resources: 16
api endpoint: https://<API-ID>.execute-api.ap-northeast-1.amazonaws.com/lambda
  • AWS Management Console で確認する場合、
    • 該当のAPIを選択:
    • デプロイしたAPIの名前(例: dev-my-app-s3-lambda-hosting)をクリックします。
    • ステージを確認:
    • 左側のメニューから Stages を選択し、該当のステージ(例: dev)をクリックします。
    • エンドポイントURLを確認:
    • ステージ設定画面でエンドポイントURLが表示されます。

App.jsxに、API GatewayのエンドポイントURLを記載します。

const response = await fetch('https://cz6tlba49h.execute-api.ap-northeast-1.amazonaws.com/lambda');

再度、以下のコマンドでフロントエンドのリソースをビルドし、S3バケットにアップロードします。

nom run build

S3バケットのエンドポイントURLにアクセスします。

Webアプリの「Fetch Data」ボタンを押下します。

「Response: Hello fron Lambda!」と出力されれば、Lambdaと連携成功です。

くれとむ

これでS3とLambdaを使ったフロントエンドとバックエンドの連携が完了したね!

チーズくん

次は独自ドメインにも挑戦してみよう!

独自ドメインの設定

さて、成功したReactアプリをS3でホストできたところで、次は独自ドメインを取得して、アプリケーションを一層魅力的にしましょう!
ここでは、AWSのRoute 53を使ってドメインを設定する方法を見ていきます。

Route 53でドメイン取得

手順
  1. AWSマネジメントコンソールに戻り、Route 53を開きます。
  2. 左側のメニューから「ドメインを登録」を選択。
  3. 好きなドメイン名を入力して、利用可能か確認します。
  4. 利用可能な場合は、ドメインを選択して必要な情報を入力し、購入します。

購入から数分後にドメイン登録完了メールが送られてきます。

チーズくん

この手順でドメインが手に入るんだ!簡単だね!

くれとむ

それじゃあ、次はドメインをS3バケットに接続しよう!

S3バケットにドメインを接続

取得したドメインをS3バケットに接続するためには、バケット名をドメイン名と一致させる必要があります。

以下の手順で設定を進めます。

手順
  1. 取得したドメイン名と同じ名前のS3バケットを作成します(※)。
  2. Route 53に戻り、登録したドメインの「ホストゾーン」を選択します。
  3. 「タイプA」レコードを作成し、S3バケットのエンドポイントを指定します。レコードの詳細を以下のように設定します。
    • レコードタイプ: A – IPv4 アドレス。
    • エイリアス: 有効にする。
    • エイリアスターゲット:対応する S3 バケットの静的ホスティングエンドポイントを選択します。

(※)既存のS3バケットをコピーしたい場合は、以下のAWS CLIコマンドで実行できます。

% aws s3 mb s3://新規S3のバケット名

% aws s3 sync s3://既存S3のバケット名 s3://新規S3のバケット名

最後に本当にS3を作成できたか確認
% aws s3 ls 

S3バケットを新規作成した場合、「パブリックアクセスをオフの無効化」、「バケットポリシーによる外部アクセスの許可」、「静的ウェブホスティングの有効化」も忘れずに行います。

バケットポリシーの設定例
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::your-backet-policy/*"
        }
    ]
}
静的ホスティングエンドポイントの確認方法

S3 バケットのエンドポイントは、バケットの「プロパティ」タブにある「静的ウェブサイトホスティング」のセクションで確認できます。
S3バケットのエンドポイントURLでWebサイトが表示されることを確認します。

例:http://<your-bucket-name>.s3-website-<region>.amazonaws.com
ドメインでのアクセス確認

自身で設定したドメイン名でWebアプリにアクセスできることを確認します。
S3のエンドポイントURLと同様に、Webアプリが表示されればドメイン接続完了です。

例:http://your-domain.click
チーズくん

これでドメインがアプリにリンクされたんだね!

くれとむ

これで取得したドメイン名でアクセス可能になったよ。
一般的なWebアプリっぽくなってきたね。
さあ、最後のステップだ!

HTTPSの有効化

Certificate Managerを利用してSSL/TLS証明書

安全なウェブサイトにはHTTPSは必須です。
これを実現するために、AWSのCertificate Managerを利用してSSL/TLS証明書を取得しましょう。

手順1: AWS Certificate Manager (ACM) で証明書のリクエスト
  1. AWSコンソールへのアクセス
  2. リージョンの変更
    • us-east-1リージョンに変更します。
      (後ほどCloudFrontdでHTTPS化をするためには、us-east-1で証明書を発行する必要があるためです。)
  3. 「証明書のリクエスト」を選択
    • ACM ダッシュボードで「証明書をリクエスト」をクリックします。
  4. 証明書タイプを選択
    • 「パブリック証明書」を選択し、「次へ」をクリックします。
  5. ドメイン名を入力
    • 証明書を適用するドメイン名を正確に入力します。
      • 例: example.com(ルートドメイン)や www.example.com(サブドメイン)。(ワイルドカード証明書を利用する場合、*.example.com を入力して、すべてのサブドメインをカバーします。)
  6. 検証方法とキーアルゴリズムの選択
    • 検証方法:「DNS 検証」を選択。
    • キーアルゴリズム:「RSA 2048」を選択。
  7. 設定を確認して送信
    • 入力内容を確認し、「リクエスト」をクリック。
手順 2: DNS 検証の設定 (Route 53 を使用)
  1. ACMの画面から、該当のドメインの証明書を選択し、ドメイン項目の「Route53でレコードを作成」を押下します。(これにより、対象ドメインのホストゾーンにACMが発行したCNAMEの値でホストゾーンが作成されます。Route53のコンソール画面からも作成は可能ですが、こちらの方が手順が少ないので、おすすめです。)
手順 3: DNS 検証の完了
  1. ACM に戻る
    • DNS レコードを追加したら、ACM の証明書詳細ページで検証が完了するのを待ちます。
    • 検証が成功すると、証明書のステータスが「発行済み」に変わります。
      (DNS の更新が反映されるまで、数分から数十分かかる場合があります。)

CloudFront を使用した HTTPS 設定手順

手順1 : CloudFront のディストリビューションを作成
  1. AWS マネジメントコンソールで CloudFront を開く
    • AWS マネジメントコンソールから CloudFront にアクセス。
  2. 「ディストリビューションを作成」をクリック
    • 「Web」を選択します(デフォルトで選択されている場合もあります)。
  3. オリジンを設定
    • オリジンドメイン:
      • S3 バケットの静的ウェブホスティングエンドポイントを入力。
        • 例: example.com.s3-website-ap-northeast-1.amazonaws.com
    • プロトコルポリシー:
      • 「HTTP」を選択。
  4. キャッシュ設定
    • キャッシュポリシー:
      • デフォルトで問題ない場合が多いですが、カスタムキャッシュを設定する場合は「キャッシュポリシーの作成」から設定を追加。
  5. ビューアプロトコルポリシー
    • 「リダイレクト HTTP → HTTPS」 を選択。
      • これにより、ユーザーが HTTP を使用してアクセスした場合に自動で HTTPS にリダイレクトされます。
  6. 証明書の選択
    • ACM 証明書を使用:
      • 「カスタム SSL 証明書を選択」をクリック。
      • 先ほど ACM で発行された証明書を選択します。
    • 代替ドメイン名 (CNAME)
      • CloudFront で使用するドメイン名を指定します(例: example.com や www.example.com)。
  7. デフォルトルートオブジェクト
    • index.htmlを指定します。
  8. 他の設定を確認
    • 他の設定はデフォルトで問題ない場合が多いですが、必要に応じてログ記録やアクセス制限を設定できます。
  9. ディストリビューションを作成
    • 「作成」をクリックして、CloudFront ディストリビューションを作成します。
手順2 : Route53のAレコードにCloudFrontを設定
  1. Route 53 のホストゾーンを開く
    • AWS マネジメントコンソールで Route 53 に移動します。
    • 対象ドメインのホストゾーンを選択。
  2. 新しい A レコードを作成
    • レコード名: 空欄(ルートドメインの場合)。
    • レコードタイプA - IPv4 アドレス を選択。
      (既にAレコードを作成済みの場合は、既存のAレコードのエイリアスをCloudFrontに変更し、保存します。)
    • エイリアスを有効にする: チェックを入れます。
    • エイリアスターゲット:
      • CloudFront のディストリビューションを選択します
        (例: example.cloudfront.net)。
  3. 保存
    • 設定を保存します。

ドメインが変更になってことに伴い、API GatewayのCORSの設定も忘れずに行う必要があります。

くれとむ

CloudFrontを使えば、応答速度もアップするんだ!

チーズくん

これで、世界中のユーザーにも安全かつ快適にWebアプリを提供できるってことだね!

まとめ

これで、AWS の複数のサービスを連携させ、React アプリケーションをホストするプロセスを完成させることができました。S3、Lambda、Route 53、CloudFront、そして ACM を組み合わせることで、高性能でセキュアなウェブアプリケーションが構築できました。

以下は、本記事の内容を振り返りつつ、各ステップの意義と利点を整理したまとめです。

S3 を利用した静的ファイルのホスティング

S3 は、静的ウェブサイトをホストするのに最適なストレージサービスです。React アプリケーションのビルド済みファイル(HTML、CSS、JavaScript)を S3 にアップロードし、そこからエンドユーザーに配信します。

  • 利点:
    • 高い可用性と耐久性を誇るストレージ。
    • AWS が提供するスケーラブルなインフラストラクチャ。
    • シンプルなアップロード手順で静的コンテンツをホスト可能。
Lambda を利用した動的バックエンドの構築

Lambda を利用することで、バックエンドの API を簡単に構築できます。サーバーレスアーキテクチャにより、サーバー管理の負担を軽減しつつ、必要な時だけリソースをスケールします。

  • 利点:
    • スケーラブルなサーバーレス環境。
    • イベント駆動型で高パフォーマンスな API を実現。
    • 使用した分だけ課金されるコスト効率の良さ。
  • 工夫点:
    • API Gateway と組み合わせて REST API を構築。
Route 53 を利用した独自ドメインの設定

Route 53 は、AWS が提供する高可用性の DNS サービスであり、独自ドメインの管理や HTTPS 証明書の設定に役立ちます。

  • 利点:
    • AWS 内の他のサービス(CloudFront、S3 など)との統合が容易。
    • ドメイン管理と DNS 設定の一元化。
    • 高速な名前解決。
  • 工夫点:
    • エイリアスレコードを利用して CloudFront に直接マッピング。
    • DNS レコード設定で CNAME を利用して HTTPS 証明書の所有権を検証。
CloudFront を利用した CDN 配信と HTTPS の有効化

CloudFront は、ウェブアプリケーションをエンドユーザーに高速かつセキュアに配信するための AWS のコンテンツ配信ネットワーク (CDN) です。ACM を利用して HTTPS を有効化し、セキュリティを強化します。

  • 利点:
    • グローバルに分散したエッジロケーションで高速配信。
    • HTTPS によるセキュアな接続を簡単に設定。
  • 工夫点:
    • ビューアプロトコルポリシーで HTTP リクエストを HTTPS にリダイレクト。

このように、AWS の強力なサービス群を活用することで、安全で高速、かつコスト効率の高い React アプリケーションのホスティングが実現しました。AWS の柔軟性と拡張性を生かして、さらにスケーラブルなウェブアプリケーションを構築していきましょう!










コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


ABOUT US
くれとむ
IT企業で働いているシステムエンジニアです。 AWSなどIT技術のトレンドを発信します。 また、日常の課題を解決するライフハック記事や実体験をもとにしたレビューも発信します。 エンジニアならではの視点で、技術の楽しさと日常の快適さを繋げます! AWS認定(CLF, SAA, DVA, SOA, SAP, DOP, ANS, SCS, MLS)、基本情報技術者、応用情報技術者、情報処理安全確保支援士、TOEIC L&R 870点 ※このサイトはアフィリエイト広告(Amazonアソシエイト含む)を掲載しています。