Cloud Run, Amplify, Netlify, VercelにNext.jsをデプロイ
このブログをCloud Run, AWS Amplify, Netlify, Vercelで運用するようにしました。DNS (Route 53) でリクエストを振り分けています。
## デプロイ
総じてデプロイは簡単だったので特に言うことはありません。
### Cloud Run





### AWS Amplify


### Netlify, Vercel
ログインしてリポジトリを選ぶだけなので省略します。
## ドメイン設定
4つデプロイしたので、全部使うことにしました。
### Cloud Run
Cloud Runのサービス一覧画面で「カスタムドメインを管理」から追加します。

### AWS Amplify
「アプリケーションの概要」→「ホスティング」→「カスタムドメイン」で設定します。
### Netlify, Vercel
Netlifyは「Domain management」、Vercelは「Settings」→「Domains」で設定します。
## ドメイン設定
それぞれに分散させたいので、Route 53で 加重ルーティング しました。

## ヘルスチェック
Route 53でヘルスチェックを設定し正常でないエンドポイントはを返さないようにしました。
- middleware.ts で GET /health に 200 を返すようにします。
- それぞれの
https://mainブランチデプロイ先/health
が動いているか確認します。 - Route 53のヘルスチェックを設定して終わりです。Route 53の料金は2024年12月時点で以下の通りです。

AWS以外のエンドポイントにHTTPSでヘルスチェックすると1エンドポイント 2.75USD/月 です。ちょっともったいないのでCloudWatchアラームで節約できるか試してみました。
まず、Lambda関数を追加します。
1const HealthCheckUrl = 'https://mainブランチデプロイ先/health';2const TimeoutMs = 8000;3export const handler = async () => {4 const abc = new AbortController();5 const timerId = setTimeout(() => abc.abort(), TimeoutMs);6 try {7 const res = await fetch(HealthCheckUrl, {signal: abc.signal});8 if (!res.ok) {9 throw new Error(`${res.status} ${res.statusText}`)10 }11 } catch (error) {12 if (error.name === 'AbortError') {13 throw new Error(`Request timed out after ${TimeoutMs}ms`);14 }15 throw error;16 } finally {17 clearTimeout(timerId);18 }19};

関数はEventBridgeで定期実行します。

エラーを検知するCloudWatchアラームを作成します。

CloudWatchアラームを見るタイプのヘルスチェックを作成し、レコードのヘルスチェックのところに設定します。

この場合の1エンドポイントあたりの料金を試算してみます。
- CE: EventBridgeの料金 ... よくわからないのでゼロ!
- CL: Lambdaの料金
- N: 2分ごと実行とすると 720回/日、31日で22320回実行されます。
- T: 1回の実行時間は Cloud Run 240ms, AWS Ampliy 600ms, Netlify 200ms, Vercel 180ms くらいなので多めに見積もって 1000ms/回 とします。
- C: 2024年12月の us-east-1 Arm 128MB の料金は 0.0000000017 USD/ms です。
- N×T×C=0.0000000017×1000×22320=0.038 USD/月 となります。
- CW: CloudWatchの料金 ... 1アラーム 0.10USD/月 です。
- CD: Route 53の料金 ... 1ヘルスチェック 0.50USD/月 です。
- C=CE+CL+CW+CD=0+0.038+0.10+0.50=0.64 USD/月 です。
Route 53でAWS外部のHTTPSだと 2.75USD/月 になりそうなので、1/4にできそうです。実際のところは来月の請求をみて確認します。
## このページはどこから?
閲覧時にレスポンスをどこが返したのか確認したいのでフッター左側に表示するようにしました。

これをやるのに環境変数をいろいろいじったのですが、それは別の記事にします。