LoginSignup
4
1

AWS Amplify hostingを利用したNext.jsのSSG

Last updated at Posted at 2023-11-14

はじめに

2023-11-14時点の情報です
アップデート等が行われていくため、記載内容と大きく変わる可能性があります

2024-02-19 にAmplify hostingでのビルドを確認したところ、ビルドするコンテナのイメージでAmazon Linux 2023は選択可能になっており、Amazon Linux 2023のNode.js 18.19.1 (2024-02-13リリース)を使いビルドすることが可能となっています

2023-11-20 大きなアップデートが入ってます
Nuxt や SSRサポート
https://aws.amazon.com/jp/blogs/mobile/introducing-support-for-hosting-any-ssr-app-on-aws-amplify-hosting/

Amplify consoleのビルド設定でAmazon Linux2023が追加され、Node.js18.18.x after も使えます

  • Next.js + Vercel での静的サイト生成(SSG)は特段の作業なく、画面のUIで設定しいくだけでVercelにデプロイしてWeb公開できます、Vercelを利用することで手軽にホスティングを行うことができます
  • Vercelと似たことができるホスティングとして、AWSのAWS Amplify ホスティング があります
  • この記事では、Amplify ホスティングを使い、Next.js SSG をデプロイ、公開をしてみます

結果、実用化

Vercel使った方が良いです

  • Amplify ホスティングを使い Next.js SSG としてWeb公開はできますが制約があります(あくまでも個人見解であり、公式ではありません)
  • 制約は、Pages Router でないといけない。App Routerではstaticページは500エラーになる。staticではない、Reactのページ相当(export default function About() { return ( <div><ul>Aboutです。</ul>/div>);})は表示はできる。
  • ビルド・デプロイのコンテナは、カスタムイメージを使う public.ecr.aws/docker/library/node:18
  • Amplify Console画面だけでは設定できず、aws amplify update-branch , aws amplify update-app を実行しないといけない。awsコマンド実行はハードルが上がります。

App Routerに関して、不明な情報含む

対応例 Amplify hosting で Next.js14 Page Router SSGを動かす

1. Amplifyのアプリ設定の確認

  • Amplify Consoleを使い設定された初期の値
    FireShot Capture 160 変数前_変更点.png

  • 赤枠のうち2箇所を以下のように変える必要がある

項目 デフォルト自動設定・読み込み値 変更後
プラットフォーム ウェブコンピューティング ウェブ
フレームワーク Next.js - SSR Next.js - SSG
  • WEB_COMPUTE -> WEB

  • 'Next.js - SSR' -> 'Next.js - SSG'

  • APP IDは3つの赤枠の最も右に位置するARNの一部です

項目 APPID
ARNの/より後がAPP_ID d3....d1

2. Amplifyのアプリ設定の変更

  • 先に記載しているプラットフォーム、フレームワークともに画面上からは変更できないので以下のようにコマンドで変更する
export APP_ID=d3....d1
aws amplify update-app --app-id ${APP_ID} --platform WEB
aws amplify update-branch --app-id ${APP_ID} --branch-name main --framework 'Next.js - SSG'

なお、aws amplify list-appsで Amplifyのアプリケーション、ホスティングの一覧が取得できる

  • 変更後
    青色枠が変わった箇所です

FireShot Capture 161 変更後.png

3. next.config.js で outputに合わせて、Amplifyでのビルド設定を変更する

  • next build(npm run build)で out ディレクトリにhtml等が出力されるので、そのディレクトリをアーティファクトとして扱う。以下のようにbaseDirectoryで .next -> out に変更
  • Amplify Console画面のビルド設定 -> アプリケーション構築の仕様の右にある編集ボタンを押して変更する
amplify.yml
version: 1
frontend:
  phases:
    preBuild:
      commands:
        - node -v
        - npm ci
    build:
      commands:
        - npm run build
  artifacts:
    baseDirectory: out
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*

4. next.config.js で outputを指定する

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  output: 'export'
}

module.exports = nextConfig

output: 'export'にすると、ローカル環境等で npm run dev で以下のようなエラーになるけど無視

 ⨯ API Routes cannot be used with "output: export". See more info here: https://nextjs.org/docs/advanced-features/static-html-export

5. ビルドするコンテナをカスタムイメージに変更

  • Amazon ECRにあるNode public.ecr.aws/docker/library/node:18 を指定します。
  • Docker Hubだと、AWS内から -> Docker Hub へのリクエスト上限の制限に引っかかるためECRで公開しているリポジトリを指定します。public.ecr.aws/docker/library/node:18.18.2 のようにバージョンを指定しても良いです
  • Amazon ECRのpublicなリポジトリは以下で確認することができます
  • 設定例
    FireShot Capture 165 - AWS Amplify - us-east-1 - us-east-1.console.aws.amazon.com.png

6. ビルドし直し

FireShot Capture 167 - AWS Amplify - us-east-1 - us-east-1.console.aws.amazon.com.png

  • 添付↑ 画面の「このバージョンを再デプロイ」を押せば良い
  • ビルドやデプロイエラーはこのボタンを押す、押せない場合は 左メニューの「ビルド設定」→「ウェブフックを作成」で、WebHook用のURLが払い出されるので curl 等で実行する

7. デプロイ確認

  • 払い出しされたURL(添付 画像の青枠URL)にアクセスして確認

FireShot Capture 168 - AWS Amplify - us-east-1 - us-east-1.console.aws.amazon.com.png

補足

Amazon Linux2でのNode.js 18.16以降, 18.18.x

  • デフォルトで作られるビルドの設定amplify.ymlでnvm install で指定バージョンをinstallし、nvm useで指定バージョンに切替える場合だとダメです。
  • 例えば、以下のように変えようにもAmazon Linux2ではGLIBC_2.27,GLIBC_2.28 not foundになりインストールエラーになる
version: 1
frontend:
  phases:
    preBuild:
      commands:
        - nvm install 18.18.2
        - nvm use 18.18.2
        - npm ci
    build:
      commands:
        - npm run build
  artifacts:
    baseDirectory: out
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*

ビルドとデプロイまで成功した時のログ例

2023-11-14T12:50:01.280Z [INFO]: # Starting phase: preBuild
                                 # Executing command: node -v
2023-11-14T12:50:01.284Z [INFO]: v18.18.2
2023-11-14T12:50:01.285Z [INFO]: # Executing command: npm ci
略
                                 > next build
2023-11-14T12:50:12.649Z [INFO]: ⚠ No build cache found. Please configure build caching for faster rebuilds. Read more: https://nextjs.org/docs/messages/no-cache
2023-11-14T12:50:12.662Z [INFO]: Attention: Next.js now collects completely anonymous telemetry regarding usage.
                                 This information is used to shape Next.js' roadmap and prioritize features.
2023-11-14T12:50:12.663Z [INFO]: You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
                                 https://nextjs.org/telemetry
2023-11-14T12:50:12.748Z [INFO]: Linting and checking validity of types ...
2023-11-14T12:50:15.229Z [INFO]: ▲ Next.js 14.0.2
2023-11-14T12:50:15.232Z [INFO]: Creating an optimized production build ...
2023-11-14T12:50:18.665Z [INFO]: ✓ Compiled successfully
2023-11-14T12:50:18.668Z [INFO]: Collecting page data ...
2023-11-14T12:50:19.953Z [INFO]: Generating static pages (0/6) ...
2023-11-14T12:50:20.069Z [INFO]: Generating static pages (1/6)
2023-11-14T12:50:20.121Z [INFO]: Generating static pages (2/6)
2023-11-14T12:50:20.747Z [INFO]: Generating static pages (4/6)
2023-11-14T12:50:20.914Z [INFO]: ✓ Generating static pages (6/6)
2023-11-14T12:50:22.062Z [INFO]: Finalizing page optimization ...
2023-11-14T12:50:22.064Z [INFO]: Collecting build traces ...
2023-11-14T12:50:24.491Z [WARNING]: ⚠ Statically exporting a Next.js application via `next export` disables API routes and middleware.
                                    This command is meant for static-only hosts, and is not necessary to make your application static.
                                    Pages in your application without server-side data dependencies will be automatically statically exported by `next build`, including pages powered by `getStaticProps`.
                                    Learn more: https://nextjs.org/docs/messages/api-routes-static-export
2023-11-14T12:50:28.034Z [INFO]: 
2023-11-14T12:50:28.041Z [INFO]: Route (pages)                              Size     First Load JS
                                 ┌ ● / (921 ms)                             2.67 kB        80.7 kB
                                 ├   /_app                                  0 B              78 kB
                                 ├ ○ /404                                   335 B          78.3 kB
                                 ├ ○ /about                                 284 B          78.3 kB
                                 ├ λ /api/hello                             0 B              78 kB
                                 └ ● /blog/[id] (1326 ms)                   400 B          78.4 kB
                                 ├ /blog/snv5gt1hehfk (738 ms)
                                 └ /blog/ez81eih--s7p (588 ms)
                                 + First Load JS shared by all              79.7 kB
                                 ├ chunks/framework-04b2df298aee5fa5.js   45.2 kB
                                 ├ chunks/main-50d44469728668f3.js        31.7 kB
                                 ├ chunks/pages/_app-df8e18ebbc1bfb84.js  297 B
                                 ├ chunks/webpack-8fa1640cc84ba8fe.js     750 B
                                 └ css/ff863e046f63fb6b.css               1.71 kB
                                 ○  (Static)   prerendered as static content
                                 ●  (SSG)      prerendered as static HTML (uses getStaticProps)
                                 λ  (Dynamic)  server-rendered on demand using Node.js
2023-11-14T12:50:28.074Z [INFO]: # Completed phase: build
2023-11-14T12:50:28.080Z [INFO]: ## Build completed successfully
2023-11-14T12:50:28.081Z [INFO]: # Starting caching...
2023-11-14T12:50:28.091Z [INFO]: # Creating cache artifact...
2023-11-14T12:50:33.777Z [INFO]: # Created cache artifact
2023-11-14T12:50:33.914Z [INFO]: # Uploading cache artifact...
2023-11-14T12:50:36.586Z [INFO]: # Uploaded cache artifact
2023-11-14T12:50:36.587Z [INFO]: # Caching completed
2023-11-14T12:50:36.630Z [INFO]: # No custom headers found.
2023-11-14T12:50:36.634Z [INFO]: # Starting build artifact upload process...
2023-11-14T12:50:36.723Z [INFO]: # Uploading build artifact '__artifacts.zip'...
2023-11-14T12:50:36.734Z [INFO]: # Uploading build artifact '__artifactsHash.zip'...
2023-11-14T12:50:37.003Z [INFO]: # Build artifact upload completed
2023-11-14T12:50:37.114Z [INFO]: # Starting environment caching...
2023-11-14T12:50:37.114Z [INFO]: # Environment caching completed
Terminating logging...

Amplify Console 設定の「platformとframework」を変更するコマンドの実行環境

aws コマンドを実行する環境がない! そんな時はCloudShellが使える

aws amplify update-app --app-id <APP_ID> --platform WEB
aws amplify update-branch --app-id <APP_ID> --branch-name main --framework 'Next.js - SSG'
  • 上述のコマンド実行環境がない場合にどうするか?
  • IAMユーザー権限での処理になるが、AWSのサービスにはCloudShellがあるので、それを使う。cloudshellからコマンド実行は手軽です。インストール等も不要でawsコマンド使えます。Cloud9のようにVPCは必要ありません。EC2作成やローカルでのコンテナ作成等も不要です。15~20分くらいで自動で停止します。

CloudShellのコンソール画面例

cloudshell.png

GitHub連携で認証した後にエラー

  • Amplify ConsoleでGitHubリポジトリ連携をする際に、GitHub認証が終わった後にエラーになるのですが、画面をリロードする。または、いくつ前の画面に戻って「リポジトリブランチの追加」画面にくると、リポジトリのプルダウンに表示されるようになります。

Vercel

  • よくできてるなあ、Next.jsフレームワークを開発したところなので相性が良い
  • 1ユーザー1ヶ月あたり20ドル、3人では60ドル/月、1$=150円だと、9000円、AWS使うよりも高いこともある
VercelとAWSについて
  • Next.js で SSG、SSRするならばVercel第一候補かな

  • AWSで対応するとなると、Amplifyはアップデートが遅いので、選択肢から外す方が良い。個人利用やMVP,PoC,プロトタイプ程度で使うには良いと思う。

  • AWSで自前(CodePipeline, CodeBuild, CodeDeploy,Cloudfront, S3, Cloudfront function)となるとけっこう大変

参考にさせてもらった情報

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1