はじめに
SSRを考慮したNext.jsアプリケーションをAWSにデプロイする際には、さまざまな選択肢があります。
バックエンドでは、ECSやEKSが一般的な選択ですが、フロントエンドの選択はより複雑です。
ここでは、一般的な構成を3つ紹介します。
構成図
1. ECS Fargate
メリット:
- 大規模なアプリケーションに適している
- 柔軟性が高く、カスタマイズが容易
- コンテナ技術により、一貫した開発・運用環境を提供
デメリット:
- セットアップが比較的複雑
- 管理の負担が大きい
- コストが高くなる可能性がある
2. (CloudFront+)Amplify
主に、Amplifyのメリットデメリットについて後述してます
CloudFrontは、導入しといたほうが無難で良いです
メリット:
- セットアップが非常に簡単
- AWSの詳細な知識がなくても使いやすい
- CI/CDが組み込まれている
- 自動スケーリングとパフォーマンス最適化
デメリット:
- カスタマイズ性に制限がある
- AWSに特化しているため、他のクラウドへの移行が難しい
- 大規模プロジェクトではコストが高くなる可能性がある
3. CloudFront + Lambda@Edge + S3
メリット:
- 高度なカスタマイズが可能
- コスト効率が良い(使用量ベースの課金)
- サーバーレスアーキテクチャによる運用の簡素化
デメリット:
- セットアップが複雑
- Lambda@Edgeにはサイズ制限がある
- AWSの深い知識が必要
4. 選択の指針
- 簡単に始めたい、または開発速度を重視する場合は (CloudFront+)Amplify
- 大規模で複雑なアプリケーション、または既存のコンテナ化されたアプリケーションがある場合は ECS Fargate
- 細かいカスタマイズが必要で、コスト最適化も行いたい場合は CloudFront + Lambda@Edge + S3
5. まとめ
これらの選択肢の中から、プロジェクトの規模、チームのスキルセット、開発のスピード、そして長期的な保守性を考慮して、最適なものを選んでいただけたらと思います。
どの方法も一長一短があるので、プロジェクトの要件に最も合うものを選択することが重要です。
※補足: CloudFront + Lambda@Edge + S3
Next.jsアプリケーションコード:
- アプリケーション全体(ページ、コンポーネント、APIルートなど)はLambda@Edge関数にデプロイされます
- これにより、サーバーサイドレンダリングや動的ルーティングが可能になります
Lambda@Edge:
- CloudFrontからのリクエストを受け取り、Next.jsサーバーを実行します
- getServerSidePropsを含む動的ページをレンダリングします
- APIルートのリクエストを処理します
S3:
- 静的アセット(.next/staticディレクトリの内容)を保存します。これには、JavaScriptバンドル、CSS、画像などが含まれます
- 静的にレンダリングされたHTMLページ(可能な場合)
CloudFront:
- ユーザーからのリクエストを受け取り、適切な場所(Lambda@EdgeまたはS3)にルーティングします
- 静的アセットのリクエストはS3に直接転送されます
- 動的ページやAPIリクエストはLambda@Edgeに転送されます
デプロイプロセス
- Next.jsアプリケーションをビルドします(npm run build)
- 生成された.nextディレクトリとサーバーコードをLambda@Edge関数にパッケージ化します
- .next/staticディレクトリの内容をS3バケットにアップロードします
この方法の利点:
- サーバーサイドレンダリングと静的アセット配信の両方を効率的に行えます
- getServerSidePropsを使用するページも問題なく機能します
- スケーラビリティが高く、サーバー管理が不要です
注意点:
- Lambda@Edgeには制限(関数サイズ、実行時間など)があるため、大規模なアプリケーションでは注意が必要です
- コールドスタート時のレイテンシーが発生する可能性があります
CI/CD:
- 開発者がコードを変更(getServerSideProps を追加など)
↓ - コードを Git リポジトリにプッシュ
↓ - CI/CD パイプラインがトリガーされる
↓ - アプリケーションのビルド
↓ - Lambda@Edge 関数の更新とデプロイ(Lambda@Edgeのコードを直接修正する必要はないが、アプリケーション全体を再ビルドして再デプロイする必要がある)
↓ - CloudFront ディストリビューションの更新