😎

Next.js (App Router) + Cloudfront + S3のデプロイ方法

2024/02/16に公開

はじめに

今回Next.jsは、App Routerの構成です。
https://nextjs.org/docs/app

静的なHTMLファイルとして出力する

https://nextjs.org/docs/pages/building-your-application/deploying/static-exports

next.config.mjsファイルを以下のように追記して静的エクスポートを有効にしてください。

next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export', // 追記
};

export default nextConfig;

その後下記のコマンドで静的なHTMLファイルとして出力します。

npm run build

プロジェクト直下にoutというフォルダができたことを確認してください。

S3の作成

今回はCloudFrontを経由させるため、静的ウェブサイトホスティングは無効のままで問題ないです。

先ほど作成したoutというフォルダ内のものをすべてアップロードしてください。

CloudFrontの作成

ディストリビューションを作成を選択、
Origin domainから先ほど作成したS3を選択してください。

Origin access control settings (recommended)をチェックし、今回は新規作成するのでCreate new OACを選択します。

署名リクエスト (推奨)にチェックにチェックが入っていることを確認し、Createを選択してください。

今回はPOSTもできるようにしたいので許可された HTTP メソッドではGET, HEAD, OPTIONS, PUT, POST, PATCH, DELETEを選択しました。

ウェブアプリケーションファイアウォール (WAF) ではセキュリティ保護を有効にしないでくださいを選択したら下へスクロールして、右下のディストリビューションを作成を選択してください。

下記のように表示がされると思うので、ポリシーをコピーを選択し、S3 バケットポリシーを更新します。

S3のバケットポリシーを編集する

作成したS3に移動します。

アクセス許可 > バケットポリシー の編集を選択し、

先ほどコピーしたポリシーを貼り付けたら、右下の変更の保存を選択してください。

デフォルトルートオブジェクトの設定

このままではCloudFrontが提供するコンテンツにアクセスした際にドメインに/index.htmlを付けないとエラーになります。

ルートディレクトリの場合はこれから説明する関数を利用してもいいのですが、CloudFrontディストリビューションの一般 > 設定で、デフォルトルートオブジェクト - オプションindex.htmlに設定するとindex.htmlの内容を表示してくれるのでこちらの方が簡単だと思います。

https://dev.classmethod.jp/articles/tips-for-cloudfront-default-root-object-2022/

ですが、サブディレクトリではこの設定ができないので関数を定義します。

サブディレクトリでデフォルトオブジェクトを設定したい場合

CloudFront > 左メニューの関数 > 関数を作成を選択、

関数名を入力したら、 関数を作成を選択、

関数コードに以下を貼り付け、変更を保存を選択してください。

function handler(event) {
    var request = event.request;
    var uri = request.uri;

    // Check whether the URI is missing a file name.
    if (uri.endsWith('/')) {
        request.uri += 'index.html';
    }
    // Check whether the URI is missing a file extension.
    else if (!uri.includes('.')) {
        request.uri += '/index.html';
    }

    return request;
}

タブから発行に移動し、関数を発行を選択してください。

関数を発行しなかった場合に関数の紐づけを行うと、次のエラーが表示されます。
The parameter FunctionAssociationArn is invalid; add_indexhtml was not found or is not published.

関数を紐づける

作成したディストリビューションを選択し、タブでビヘイビアに移動します。対象となるものを選択したら編集を選択してください。

下へスクロールし、関数の関連付けのビューワーリクエストから関数タイプCloudFront Functionsを選択、先ほど作成した関数を選択したら、変更を保存を押してください。

アクセスの確認

CloudFront > ディストリビューションドメイン名にアクセスして表示が確認されれば問題ありません。

CloudFrontのキャッシュ削除

アップロードするファイルを変更した際は必ずCloudFrontのキャッシュ削除を行うようにしてください。
https://blog.denet.co.jp/cloudfront_auto/

/*

参考にさせていただきました

https://qiita.com/y_inoue15/items/c637dd2e269f7ab50e38

終わりに

何かありましたらお気軽にコメント等いただけると助かります。
ここまでお読みいただきありがとうございます🎉

Discussion