Next.jsアプリをTerraformとCloudBuildを使ってCloud Runで動かす
Updated Date: 2024/01/01 02:55
自社ではGCPを使ってNext.jsのSSGをフロントエンドサーバーとしてCloud Runで動かしている。
バックエンドのデプロイの仕組みはわかっているつもりだったが、Next.jsの環境変数の設定周りで苦労したので知見として残しておく。
何が起きたか
ありのまま起こったことを話すと、Next.jsのWebサービスは NEXT_PUBLIC
から始まる環境変数を持っていて、これがアプリのビルド時に環境変数にとして埋め込まれる。
つまり、バックエンドの実装の場合、基本的にDockerコンテナを動かすときに環境変数を渡せばよいのだが、Next.jsだとそうはいかないということだ。
なので、以下のような構成で環境変数を設定するようにした。
# | サービス名 | 内容 |
---|---|---|
1 | Terraform | 使う環境変数を定義(1) |
2 | Cloud build(cloudbuild.yaml) | (1)で定義した環境変数をdocker build時に設定(2) |
3 | Dockerfile | (2)の環境変数をARGで受け取りENVに設定するよう記述 |
4 | Cloud Run | 何も設定なし |
ややこしいポイント
この仕組みだとNEXT_PUBLIC系の環境変数を追加・削除するときは3回箇所(1,2,3)も編集しなければならない。 これがわりとややこしい。
改善案
ということで改善案がこちら。
# | サービス名 | 内容 |
---|---|---|
1 | Terraform | 使う環境変数を定義(1) |
2 | Cloud build(cloudbuild.yaml) | (1)で定義した環境変数をenvに指定 |
3 | Dockerfile | 何も設定無し |
4 | Cloud Run | 何も設定なし |
1つステップが減った。これによりTerraformとcloudbuild.yamlのみを修正するだけで良くなった。どういうことか説明するために cloudbuild.yml
の一部を抜粋する。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
- id: 'yarn build'
name: node
entrypoint: yarn
args: ['run', 'build']
env:
- 'NEXT_PUBLIC_FIREBASE_API_KEY=$$FIREBASE_API_KEY'
- 'NEXT_PUBLIC_FIREBASE_APP_ID=$$FIREBASE_APP_ID'
- 'NEXT_PUBLIC_TEST_ENV=$$TEST_ENV'
secretEnv: [
'FIREBASE_API_KEY',
'FIREBASE_APP_ID',
]
- id: 'build'
name: 'gcr.io/cloud-builders/docker'
entrypoint: 'sh'
args: [
'-c',
'docker build
--cache-from hoge-app:latest
--build-arg PORT="3335"
-f ./docker/Dockerfile
-t hoge-app:latest
.'
]
waitFor:
- 'yarn build'
つまり ソースをyarn buildして環境変数を埋め込む → それをDockerコンテナとしてまとめる
ということをやっている。
このとき、 .gitignore
から .next
ディレクトリや out
などNext.js・TypeScriptのbuild時の出力ディレクトリを除くことを忘れてはならない。
まとめ
Dockerサイコー!という感じでなんでもDocker化せず、仕組みを簡素化するために、有り余るビルドサービス側の資源を活用するのも方法の1つ。 ちなみにビルド時間はそんなに変わらないと思う。