🛠️

AmplifyにNext.js14をデプロイしようとしてつまづいたポイント

2024/04/02に公開

背景

Sabo Learn(サボラーン)というプロダクトを開発しています。

そのフロント部分(Next.js Ver14.1.0)をgithubのリポジトリと連携して、AWSのAmplifyにデプロイしようとしたところ、エラーでつまづきました。

なんとか自力で解決できたので、その方法を共有します。

つまずいたポイント

  1. ディレクトリ構造によるエラー
  2. 環境変数の取得エラー

① ディレクトリ構造によるエラー

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/**/*

- デプロイ設定の変更

下層にアプリがある場合、自動判定でplatformframeworkの部分が誤った設定になってしまいます。

これも、通常はルートディレクトリに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

に変更されていれば成功です。

https://zenn.dev/wakkunn/articles/be748e71d405d1

- 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だけにリポジトリを分ければ簡単な話だったのですが...

同じようなことをしようとしている人の助けになれば幸いです。

GitHubで編集を提案

Discussion