AmplifyにNext.js14をデプロイしようとしてつまづいたポイント
背景
Sabo Learn(サボラーン)というプロダクトを開発しています。
そのフロント部分(Next.js Ver14.1.0)をgithubのリポジトリと連携して、AWSのAmplifyにデプロイしようとしたところ、エラーでつまづきました。
なんとか自力で解決できたので、その方法を共有します。
つまずいたポイント
- ディレクトリ構造によるエラー
- 環境変数の取得エラー
① ディレクトリ構造によるエラー
githubと連携させるときは、ルートディレクトリにアプリを置く必要があります。
というのも、ルートディレクトリの内容を見て、アプリケーションの種類を判別し、自動的に以下のようなyamlファイルを作成してくれるからです。
version: 1
frontend:
phases:
preBuild:
commands:
- npm ci --cache .npm --prefer-offline
build:
commands:
- npm run build
artifacts:
baseDirectory: .next
files:
- '**/*'
cache:
paths:
- .next/cache/**/*
- .npm/**/*
npm ciコマンドについて
通常npmを使うときnpm install
とすると思います。以下のような違いがあります。
-
npm install
は package.json を参照して依存関係をインストール -
npm ci
は、package-lock.json を参照して依存関係をインストール
npm install
の場合、パッケージのバージョン指定に「メジャーバージョンのみ固定」などの幅があると、インストールのタイミングによってバージョンの違いが発生することがあります。
それに対してnpm ci
の場合、package-lock.json が作成された時点のバージョンのパッケージをインストールすることが可能です。
.npm --prefer-offline
の部分は、npm ci
を実行すると毎回node_modules
が新しく作り直されるので、キャッシュして高速化するための記述です。
しかし、以下のように複数のディレクトリをリポジトリにまとめて、githubで管理したい場合もあると思います。
app
┣ frontend
┗ backend
このリポジトリをデプロイしようとすると、yamlファイルは以下のようになります。
version: 1
frontend:
phases:
# IMPORTANT - Please verify your build commands
build:
commands: []
artifacts:
# IMPORTANT - Please verify your build output directory
baseDirectory: /
files:
- '**/*'
cache:
paths: []
buildコマンドが空欄になっています。
- rootディレクトリを明示する
下層にアプリがある場合、Amplify.yamlを以下のように書くことでデプロイできます。
version: 1
applications:
- appRoot: app/frontend
frontend:
phases:
preBuild:
commands:
- npm ci --cache .npm --prefer-offline
build:
commands:
- npm run build
artifacts:
baseDirectory: .next
files:
- '**/*'
cache:
paths:
- .next/cache/**/*
- node_modules/**/*
- デプロイ設定の変更
下層にアプリがある場合、自動判定でplatform
とframework
の部分が誤った設定になってしまいます。
これも、通常はルートディレクトリにNext.jsのアプリがあれば自動判定されるので、イジる必要がないのですが、前述のような階層構造でデプロイしようとする場合、間違った判定をされてしまうので、マニュアル操作で修正する必要があるのです。
以下のコマンドは、事前にaws cliをインストールする必要があります。公式ドキュメント
これは、ターミナル上でawsを操作するためのもので、以下の記事で詳しく解説されています。
aws amplify update-app --app-id ○○○○○ --platform WEB_COMPUTE --profile ○○○
aws amplify update-branch --app-id ○○○○○ --branch-name main --framework 'Next.js - SSR' --profile ○○○
これで、Amplifyの設定画面で、
プラットフォーム -> ウェブコンピューティング
フレームワーク -> Next.js - SSR
に変更されていれば成功です。
- rootディレクトリにpackage.jsonを置く
しかし、これだけでは、まだデプロイできません。
githubからクローンするときに以下のようなエラーが発生します。
CustomerError: Cannot read 'next' version in package.json.
Amplifyは、githubからクローン → yamlファイルに従ってビルド
という流れで実行されるのですが、クローンするときにはNext.jsのアプリケーションがどこにあるか分かりません。
先ほども書きましたが、Amplifyはpackage.jsonの存在とその中身によってアプリケーションを識別しています。
ルートディレクトリにNext.jsのアプリケーションがある前提でクローンしようとするのですが、ルートディレクトリにpackage.jsonがないと、エラーになってクローンしてくれません。
Next.jsのアプリケーションがどこにあるか明示できればいいのですが、yamlファイルと違って、クローンの段階ではディレクトリを明示することができません。
どうすれば良いかと言うと、ローカル開発環境のルートディレクトリで、
npm install
npm next install
を実行して、pushしておきます。
こうすることで、エラーにならずにクローンすることができます。
② 環境変数の取得エラー
Next.jsのアプリケーション内で、
process.env.SECRET_KEY
のように記述すると、env
ファイルに記述している環境変数を取得できます。
env
ファイルには、通常秘匿情報が含まれるためgithubで管理すべきではありません。
しかしデプロイするときには、envファイルがなければ環境変数を取得することができません。
そこでyamlファイルに以下のように追記します。
version: 1
applications:
- appRoot: frontend/app
frontend:
phases:
preBuild:
commands:
- npm ci
build:
commands:
+ - echo "SECRET_KEY=$SECRET_KEY" >> .env.production
- npm run build
artifacts:
baseDirectory: .next
files:
- '**/*'
cache:
paths:
- .next/cache/**/*
- node_modules/**/*
SECRET_KEY
はただの環境変数名です。
これは、Amplifyのコンソール画面の環境変数タブから設定することができます。
.env.production
というファイルを作成して"SECRET_KEY=$SECRET_KEY"
という行を追記するというコマンドです。
このとき、Amplifyで環境変数を設定していると、$SECRET_KEY
の部分に値が展開されます。
まとめ
特にディレクトリ構造によるデプロイエラーは、ログを見ても原因が分からず、かなり時間がかかってしまいました。
素直にNext.jsだけにリポジトリを分ければ簡単な話だったのですが...
同じようなことをしようとしている人の助けになれば幸いです。
Discussion