Next14をAmplify Hostingで動かす

TL;DR

  • Next.js 14をAmplify Hostingで動かす(動いた)
  • Next.js 14になってRuntimeのNodeバージョンが最小で18.17になった
    • これによりAmplify HostingのRuntimeバージョンが合わず、実行時エラーになっていた
  • 2023/11/6時点の内容
  • Amplify Hostingの場合、BuildのイメージとRuntimeのイメージは異なる
  • AmplifyでBuildする時にCustom Build Imageが必要

経緯

Next.js 14がアナウンスされました。 もともとAmplify HostingでNext.js 13を動かしている環境があったので、試しにNext14にアップグレードしてデプロイしたところ 以下のような実行時エラーが出ました。

class NextRequest extends Request {
ReferenceError: Request is not defined

これはNextを動かしている環境のNodeのバージョンが古いために出ている模様。

  • Next14からはNodeの最小バージョンが18.17になったこと
  • Amplify HostingのRuntimeはNode16で動いていること

これにより実行時エラーになっているようです。

issue にあがっていたので しばらくwatchしていたところNode18.17に対応したとのコメント が。

ということで試してみたところ、無事Next14をAmplify Hositngで動かすことができたので手順を記録します

手順

すでにAmplifyでNextをbuild&deployしている環境があることを前提にしています。 まだ何も作成していない、という場合は 公式 を参考にしてください。

1. Custom Build Imageを作る

issueのコメント を見るとAmplifyでBuildした時のNodeのバージョンでRuntimeのNodeのバージョンを決めるようになったと書かれています。

AmplifyはBuildする時にCustom Build ImageとしてECRなどに事前に作成したDocker Imageを利用してBuildさせることができます。 ここでNode18.17でBuildさせるようにすると、SSRなどでNext.jsを動かす場合もNode18.17で動かしてくれるようです。

issueでは public.ecr.aws/docker/library/node:18.17.0 をテスト用に記載してくれていますが このイメージには aws-cli が入っていないため、このまま使ってもAmplifyのBuild前フェーズでcodecommitからsourceを落とすことができず失敗しました。

Node18.17でBuildができればよいのだろう、ということでCustom Build Imageを作ってbuildするようにします。

まず、Dockerfile です。今回は amazonlinux:2023 をベースにしました。

 1FROM amazonlinux:2023
 2
 3# Install foundamental packages
 4RUN dnf install -y tar gzip unzip
 5
 6# aws-cli
 7RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
 8RUN unzip awscliv2.zip
 9RUN ./aws/install
10
11# nvm
12RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
13
14# node
15RUN . ~/.nvm/nvm.sh && nvm install 18.17.0
16
17RUN echo -e "\
18export NVM_DIR=\"\$HOME/.nvm\"\n\
19[ -s \"\$NVM_DIR/nvm.sh\" ] && \. \"\$NVM_DIR/nvm.sh\"\n\
20" >> ~/.bashrc
21
22# git
23RUN dnf install -y git
24
25ENTRYPOINT [ "/bin/bash" ]

aws-cli はcodecommitからソースを落とす際にログインするためにAmplify Buildの内部で利用されます。 また、 nvm を使ってNode18.17.0をインストールしています。

このDockerをイメージを作ってpublic ECRにリポジトリを作ってpushします

まずECRリポジトリを作ります。 public ECRにするため、regionは us-east-1 にします。

1aws ecr-public create-repository --repository-name docker-amplify-build-image --region us-east-1

実行後、リポジトリのURLが返却されるのでメモしておきます

次に上記のDockerfileを使ってDocker ImageをBuildします

1# build image
2docker build . -t docker-amplify-build-image:node18.17.0
3
4# add tag
5docker tag docker-amplify-build-image:amazonlinux2023 public.ecr.aws/[ECR作った時に返却されたURL]/docker-amplify-build-image:node18.17.0

ECRにログインしてImageをpushします

1aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws
2
3docker push public.ecr.aws/[ECR作った時に返却されたURL]/docker-amplify-build-image:node18.17.0

これでCustom Imageをpublic ECRに配置できました。

2. Amplify Build設定

Amplify Consoleを開き、 Build settings

画面下部の Build image setttings のところをedit

BuildImageのところに以下のように設定します

public.ecr.aws/[ECR作った時に返却されたURL]/docker-amplify-build-image:node18.17.0

picture 0

3. Amplifyでビルド&デプロイ

Next.js14に対応した状態のソースコードをAmplifyに設定しているCodeCommitにpushして ビルド&デプロイを実行すればOK。

ここまでの設定によりnode18.17.0でbuildされ、Nextが動くRuntimeも18.17.0で動作するはずです。

ちなみにNode20でbuildしたらどうなるかと思ってやってみたら、build後のdeployで対応していないnode versionエラーになりました

最後に参考までにbuild時の amplify.yml です。 これはNext13/Node16の時と今回のNext14/Node18の時とで変える部分はありませんでした

 1version: '1.0'
 2applications:
 3  - appRoot: frontend
 4    frontend:
 5      phases:
 6        preBuild:
 7          commands:
 8            - npm ci
 9        build:
10          commands:
11            - npm run build
12      artifacts:
13        baseDirectory: .next
14        files:
15          - '**/*'
16      cache:
17        paths:
18          - node_modules/**/*
19          - .next/cache/**/*