Next.jsをCloudbuildでGAEにデプロイ
TL;DR
Next.jsをGoogle App Engine (GAE) で動かすまでの記録。CloudflareはAMPページがなんかエラーしたので一旦やめておいた。
要件として、以下が欲しかった。
- Github連携で、push/prなどでデプロイ
- Webhookでcurlなどでデプロイ
ということで、Cloudbuildにトリガーを作ってGAEにデプロイすることが目標。
GAEにデプロイ
とりあえず動くようにしたいので、まず設定ファイルを書いてデプロイする。 個人ブログを載せるだけなのでできるだけ無料枠で収まってほしい。一応予算アラートも設定しておく(【クラウド破産の回避術】Google Cloud (GCP)の予算アラートで安全なクラウド運用を実現!)。
設定については以下のサイトを参考にした。
- Google App Engineを無料で運用する方法(2018年版)
- Google App Engineを出来るだけ無料枠で収めるためのオートスケール設定
- Next.jsをGAEで動かす(CloudBuildから自動デプロイ)
app.yaml
env: standard
runtime: nodejs14
instance_class: F1
service: default
handlers:
- url: /_next/static
static_dir: .next/static
- url: /(.*\.(gif|png|jpg|ico|txt|svg|webp))$
static_files: public/\1
upload: public/.*\.(gif|png|jpg|ico|txt|svg|webp)$
- url: /.*
script: auto
secure: always
default_expiration: "12h" # 静的ファイルのキャッシュ期間
env_variables:
NODE_ENV: "production"
automatic_scaling:
target_cpu_utilization: 0.95
target_throughput_utilization: 0.95
min_idle_instances: 0
max_idle_instances: 1
min_instances: 0
max_instances: 1
min_pending_latency: 5000ms
max_pending_latency: automatic
max_concurrent_requests: 80
gcloud経由でとりあえずdeployしてテストしておく。.gcloudignore
はnode用のファイルが自動で生成される。coverage
などの不必要なファイルを書き込んで置きたい。
gcloud app deploy app.yaml --project $PROJECT_ID
この時点で、権限を設定する必要があった。以下の権限を最終的に有効にした。
- AppEngine (GAEにデプロイするときにそもそも必要)
- SecretManager (Webhookのシークレット作るときに必要)
- Service Accounts (CloudBuild経由でデプロイするときに必要)
CloudBuildの設定
設定ファイル
cloudbuild.yaml
steps:
- id: install packages
name: node:14
entrypoint: yarn
args: ["install"]
- id: build
name: node:14
entrypoint: yarn
args: ["build"]
- name: gcr.io/cloud-builders/gcloud
args: ["app", "deploy", "app.yaml", "--project=$PROJECT_ID", "--quiet"]
cloudbuildでは、変数を書いておくとよしなに置換してくれる機能がある。今回はデプロイ先を自動で置換してもらえるように$PROJECT_ID
を使用した。
詳細は、変数値の置換を参照。
また、nodeのバージョンなども、node:${version}
という形式で指定できるので、一応指定した。
Cloud BuildとGithubを連携
Google Cloud BuildというGithub Appを連携させる。
そのあと、プロジェクトのRegionと関係なく
"global" regionでトリガーを作成し、Githubの該当レポジトリと連携させる。
同一リージョンなら行けると思っていたが、FAILED_PRECONDITION: generic::failed_precondition: no concurrent builds quota available to create builds.
というエラーが出てしまった (参考)。
あとはpushするなり、手動でトリガーを起動するなりして動くかチェックする。あと、Service Accountsの権限がないとここでエラーした。
Webhookでのトリガー作成
webhookを選ぶだけ。シークレットキー作成する必要があるので、SecretManagerの権限がいる。-d
でボディを明示しないとエラーになる。
curl -X POST -d '{}' $preview_url