Gojabako ZoneKei Ito

Cloud Run, Amplify, Netlify, VercelにNext.jsをデプロイ

に公開に更新)履歴 (2)

このブログをCloud Run, AWS Amplify, Netlify, Vercelで運用するようにしました。DNS (Route 53) でリクエストを振り分けています。

## デプロイ

総じてデプロイは簡単だったので特に言うことはありません。

### Cloud Run

ヘッダーの「リポジトリを接続」をクリックします。#img1
ヘッダーの「リポジトリを接続」をクリックします。
GitHubのアカウントを接続して、リポジトリを選びます。#img2
GitHubのアカウントを接続して、リポジトリを選びます。
ビルドタイプはBuildpacksの方を選びます。#img3
ビルドタイプはBuildpacksの方を選びます。
今回のアプリはこのブログなので未認証の呼び出しを許可して、作成をクリックします。#img4
今回のアプリはこのブログなので未認証の呼び出しを許可して、作成をクリックします。
しばらく待ったらデプロイ完了して表示できました。簡単でした。#img5
しばらく待ったらデプロイ完了して表示できました。簡単でした。

### AWS Amplify

GitHubを選択します。#img6
GitHubを選択します。
リポジトリ選択以外はいじらずにデプロイできました。簡単でした。#img7
リポジトリ選択以外はいじらずにデプロイできました。簡単でした。

### Netlify, Vercel

ログインしてリポジトリを選ぶだけなので省略します。

## ドメイン設定

4つデプロイしたので、全部使うことにしました。

### Cloud Run

Cloud Runのサービス一覧画面で「カスタムドメインを管理」から追加します。

Cloud Runでドメイン追加画面を閉じた後、DNSレコードは「操作」列のボタンの先に隠れています。#img8
Cloud Runでドメイン追加画面を閉じた後、DNSレコードは「操作」列のボタンの先に隠れています。

### AWS Amplify

「アプリケーションの概要」→「ホスティング」→「カスタムドメイン」で設定します。

### Netlify, Vercel

Netlifyは「Domain management」、Vercelは「Settings」→「Domains」で設定します。

## ドメイン設定

それぞれに分散させたいので、Route 53で 加重ルーティング しました。

Cloud Runのドメインマッピングはプレビュー版なので少なめにしました。#img9
Cloud Runのドメインマッピングはプレビュー版なので少なめにしました。

## ヘルスチェック

Route 53でヘルスチェックを設定し正常でないエンドポイントはを返さないようにしました。

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

AWS以外のエンドポイントにHTTPSでヘルスチェックすると1エンドポイント 2.75USD/月 です。ちょっともったいないのでCloudWatchアラームで節約できるか試してみました。

まず、Lambda関数を追加します。

#code1
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};
タイムアウトは初期値の3秒だとたまに足りないので10秒にしています。#img11
タイムアウトは初期値の3秒だとたまに足りないので10秒にしています。

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

2分ごとに定期実行しています。#img12
2分ごとに定期実行しています。

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

状態変化はSNS経由でメール通知されるようにしました。#img13
状態変化はSNS経由でメール通知されるようにしました。

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

これはAWSエンドポイントのヘルスチェックになるはず。#img14
これはAWSエンドポイントのヘルスチェックになるはず。

この場合の1エンドポイントあたりの料金を試算してみます。

Route 53でAWS外部のHTTPSだと 2.75USD/月 になりそうなので、1/4にできそうです。実際のところは来月の請求をみて確認します。

## このページはどこから?

閲覧時にレスポンスをどこが返したのか確認したいのでフッター左側に表示するようにしました。

Netlifyが返した場合#img15
Netlifyが返した場合

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