メインコンテンツまでスキップ

本カタログの概要

Lambda Web Adapter を利用したウェブアプリケーション開発を行うための推奨構成です。

カタログ概要

本カタログに含まれるソースコードの構成図です。

アーキテクチャ

本カタログに含まれるドキュメントおよびソースコードは、以下のような構成を前提としています。

主なポイントは以下になります。

  • AWS Lambda 上に、ビルド済みの React Router v7 または Next.js 15 アプリケーションをデプロイ(AWS Lambda Web Adapterを使用)

  • CloudFront 経由でアクセスさせることでキャッシュとカスタムドメインが適用できる Function URLs へのアクセスには IAM 認証を適用し、CloudFront 経由でしかアクセスできないようにする

  • IAM 認証の解決には、Origin Access Control (GET) と、SigV4 (POST/PUT) 署名をする Lambda@Edge 関数を作成・利用する

  • 静的ファイルは別途 S3 に振り分けるようにし(※必須ではない)、コンテナ再デプロイなしでも静的ファイルのみ追加・更新ができるようにしたり、Lambda パッケージ容量の最適化が可能

    • 大量の画像ファイルや PDF ファイルなどを公開・配信する場合、こちらの構成がおすすめです。
    • 静的ファイルを S3 に振り分けなくても、Lambda コンテナ内から画像が配信されるようにして、CloudFront 段でキャッシュさせる形が構成としてはよりシンプルになります。

AWS Lambda Web Adapter とは?

SSR タイプのウェブフレームワークの場合、AWS Lambda で実行させるためには、Lambda のイベントにマッピングされた HTTP リクエストペイロードをウェブフレームワークのエントリーポイントに合わせて変換を行う処理が必要です。

AWS Lambda Web Adapter は、これらの処理を個別のライブラリごとに行わなくても実行できるように、Lambda Extensions を利用して内部的にアプリケーションサーバーを立ち上げ、AWS Lambda から直接 Function URL を入り口とした HTTP リクエスト・レスポンスをハンドリングできるようにしてくれます。

ECS Fargate などで利用できる Docker イメージを、ほぼそのまま(Dockerfile に概ね1~数行追加するだけで)AWS Lambda で利用可能になりますので、アプリケーションの実装に今回のようなサーバーレス構成のための特別な改修等のお手入れをする必要がないことが特徴です。

Lambda Web Adapter の詳細については、公式 GitHub も合わせて確認してください。

利用する Web Application Framework - React Router v7

本カタログでは、ウェブアプリケーション開発フレームワークとして、「React Router v7」を利用します。React Router v7 は Remix と React Router が統合され、それぞれ「フレームワークモード(SSR - Server-side rendering)」と「ライブラリモード (SPA - Single Page Application)」の形で利用することができます。

本カタログには、サーバーレスでサーバーサイドレンダリングが可能となる仕組みである AWS Lambda Web Adapter を利用し、React Router v7 をフレームワークモードで利用する SSR Application を開発するための構成が含まれています。このユーザーガイドもそれに基づいて説明されていますのでご参考ください。

カタログのプロジェクトは ~/serverless-frontend-application-stack というディレクトリに配置されています。

全体のプロジェクト構成

本カタログ全体のディレクトリおよびファイル構成です。

serverless-frontend-application-stack/

├── .vscode/ # VSCode 設定ファイル
│ ├── extensions.json
│ └── settings.json

├── deploy/
│ └── cloudformation/
│ ├── lambda.yaml
│ └── s3-cloudfront.yaml

├── public/ # 画像など静的ファイル
│ └── fabicon.ico

├── src/
│ ├── components/ # 再利用可能な React UI コンポーネント
│ ├── hooks/ # 各種カスタムフックを定義
│ ├── layouts/ # React Router v7 の layout コンポーネントを定義
│ ├── lib/ # 各種Util, shadcn-ui など外部ライブラリ
│ ├── pages/ # 各ページごとの基点コンポーネントおよびそのページ内での分割コンポーネント
│ ├── states/ # 状態管理ライブラリ「jotai」を利用した atom を定義
│ ├── styles/ # スタイル(CSS)定義
│ ├── types/ # 型定義
│ ├── env.server.ts # サーバーサイドの環境変数
│ ├── root.tsx # React Router v7 アプリケーションとしての基点
│ ├── routes.ts # ページルーティングの定義
│ └── util.ts # 各種ユーテリティ

├── .env # ローカル実行時の環境変数定義
├── .editorconfig
├── .gitignore
├── biome.json
├── build-app.sh # ビルドスクリプト
├── components.json # shadcn-ui の設定
├── Dockerfile
├── postcss.config.js # Tailwind CSS 関連設定
├── package.json
├── package-lock.json
├── react-router.config.ts
├── tailwind.config.ts
├── tsconfig.json
└── vite.config.ts

Dockerfileの構成

Dockerfile は以下のように構成します。各記述に関する詳細はインラインコメントをご参考ください。

FROM public.ecr.aws/lambda/nodejs:22 as builder

WORKDIR "/var/task"

ADD . .

# React Router v7 はビルド結果に node_modules を含めないため、--omit=dev 指定で npm install を実行しておきます。
RUN npm install \
&& npm run build \
&& cp package.json .dist/server/ \
&& cp package-lock.json .dist/server/ \
&& cd .dist/server/ \
&& npm install --omit=dev

# AWS public ECR に登録されている公式イメージの利用を推奨
FROM public.ecr.aws/lambda/nodejs:22

# Lambda Web Adapter
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.9.1 /lambda-adapter /opt/extensions/lambda-adapter

# React Router v7 は、ビルドすると .dist/server と .dist/client が分かれて生成されます。
# .dist/server の内容はコンテナに入れて AWS Lambda にデプロイし、
# .dist/client の内容もそのままコンテナに入れるか、別途 S3 に保存して CloudFront から振り分けることでキャッシュ戦略のカスタマイズや最適化を行うことが可能です。

# Server side assets
COPY --from=builder /var/task/.dist/server/index.js /var/task/index.js
COPY --from=builder /var/task/.dist/server/assets /var/task/assets
COPY --from=builder /var/task/.dist/server/node_modules /var/task/node_modules
COPY --from=builder /var/task/.dist/server/package.json /var/task/package.json

# Client side assets
COPY --from=builder /var/task/.dist/client/ /var/task/public/

# Next.js やその他のウェブアプリケーションは、それぞれ静的ファイルに対するアプローチや設定が異なるため、
# フレームワーク独自のカスタムヘッダーなど、
# 構成上問題が起きないように設定などをカスタマイズする必要が出てくる場合があります。
# Dockerfile で対応するか、CloudFront や Lambda@Edge で対応するかといった設計の検討と確認を行ってください。

# React Router v7 はその構成のシンプルさ、可能な限り Web Standards に合わせるという方針によって
# Lambda Web Adapter を利用するフロントエンドアプリケーションとして、親和性・相性に優れています。

WORKDIR "/var/task"

ENV NODE_ENV=production
ENV PORT=3000

ENTRYPOINT ["npm", "run", "start"]

参考資料

Lambda Web Adapter を利用した Dockerfile 作成の詳細についてもっと知りたい方は、以下の公式 GitHub のドキュメントをご参考ください。