Next.jsをGAEで動かす(CloudBuildから自動デプロイ)
Next.jsアプリをGoogle App Engine(GAE)のスタンダード環境にデプロイする方法をまとめておきます。GitHubなどからCI/CDができるようにGoogle Cloud Buildから自動デプロイする方法も合わせて紹介します。
Next.jsアプリがすでに作成されているという前提で説明をはじめます。
app.yaml
の設定
1. まずはプロジェクト内のルートなどにapp.yaml
を作成します。GAEへのデプロイ設定の大部分はここで行います。今回は例として以下のようにします。
env: standard # スタンダード環境(省略可)
runtime: nodejs14 # Node.js 14を使う(追記: nodejs16も使えるようになりました)
instance_class: F4
service: default # GAEのサービスの名前。frontendとかでも良いかも
handlers:
- url: /_next/static
static_dir: .next/static
- url: /(.*\.(gif|png|jpg|ico|txt|svg))$
static_files: public/\1
upload: public/.*\.(gif|png|jpg|ico|txt|svg)$
- url: /.*
script: auto
secure: always
default_expiration: "12h" # 静的ファイルのキャッシュ期間
env_variables:
NODE_ENV: "production"
automatic_scaling:
min_instances: 0 # 動かしてないときはインスタンスを0にする
簡単に説明をしておきます
-
instance_class: F4
だと メモリ 1024 MB / CPU 2.4 GHz という制限になります。他の設定値はインスタンスのクラスをどうぞ。 -
handlers
ではURLのパターンごとの処理を設定します。-
static_dir
やstatic_files
にマッチしたファイルは静的ファイルとしてアップロードされるようになります(詳細) - Next.jsのデフォルト設定ではビルド時に静的ファイルが
.next/static
ディレクトリの中に出力されるようになっています(参考)。 - Next.jsでは
public
ディレクトリ内に静的ファイルを入れることができます。実際のファイルへのURLには/public
がつかずルートからの参照になるため、指定がややこしくなります。今回はNuxt.jsのドキュメントを参考に指定しました。
-
- 静的ファイルのキャッシュ期間は
default_expiration
で指定できます。今回は12h
(12時間)としてみました。 -
automatic_scaling
では最小インスタンス数や最大インスタンス数などを指定できます。ドキュメントを参考に、より細かな設定を行うことをおすすめします。
package.json
の設定
2. {
"scripts": {
"dev": "next dev",
+ "build": "next build",
+ "start": "next start -p $PORT",
},
}
GEAでNext.jsを動かすには、ビルドした上でnext start
を実行することになります。GAEではpackage.json
にstart
スクリプトが書かれていると、アプリ起動時に実行してくれます。
デフォルトでは、ランタイムは node server.js を実行してアプリケーションを起動します。package.json ファイルで start スクリプトを指定すると、ランタイムは代わりに指定された起動スクリプトを実行します。
アプリケーションの起動
.gcloudignore
の設定
3. .gcloudignore
には、サービスをデプロイするときにGAEにアップロードしないファイルを指定します。詳しい書き方はこちらの記事が参考になります。
たとえば以下のように指定します。
.gcloudignore
.gitignore
node_modules/
これに加えて/components
や/pages
などのビルド後は不要になるソースファイルも.gcloudignore
に追加できます。これらのファイルを/src
ディレクトリにまとめている場合は/src
を追記すればOKです。
4. ローカルからのデプロイを試す
ここまで設定ができていればビルドしてデプロイができます。ローカルからデプロイするにはgcloud CLIのセットアップが完了している必要があります。
$ npm run build
$ gcloud app deploy app.yaml --project GCPのプロジェクト名
以下のようにpackage.json
にデプロイ用のscriptを追加しておいても良いと思います。
{
"scripts": {
+ "deploy:gae": "npm run build && gcloud app deploy app.yaml --project=プロジェクト名",
},
}
これでローカルからはnpm run deploy:gae
でデプロイができるようになります。
5. CloudBuildからのデプロイ
CloudBuildからGAEするためにはサービスアカウントのIAM設定が必要です。このあたりはドキュメントで分かりやすく解説されています。
cloudbuild.yaml
ステップの中でnpm install
とnpm run build
を実行したうえでGAEのデプロイコマンドを叩くようにします。
steps:
- name: node
entrypoint: npm
args: ["install"]
- name: node
entrypoint: npm
args: ["run", "build"]
- name: gcr.io/cloud-builders/gcloud
args: ["app", "deploy", "app.yaml", "--project=foo", "--quiet"]
--quiet
はデプロイ時に表示される「デプロイしますか?」のような確認をスキップするために指定します。
yarn
を使う場合
CloudBuildのステップでパッケージのインストールやビルドにyarnを使いたい場合はentrypoint
をyarn
にします。
steps:
- name: node
entrypoint: yarn
args: ["install"]
- name: node
entrypoint: yarn
args: ["build"]
- name: gcr.io/cloud-builders/gcloud
args: ["app", "deploy", "app.yaml", "--project=foo", "--quiet"]
nodeバージョンを指定したい場合
Node.jsのバージョンを指定したい場合はname
の値をnode:バージョン
とします。
- id: install-packages
name: node:14
entrypoint: yarn
args: ["install"]
以上の設定ができていれば、CloudBuildからGAEへのデプロイができるはずです。
Discussion