🐳
GitHub ActionsでNext.js 13のDockerコンテナーにNEXT_PUBLIC_を渡す
はじめに
最近ちょくちょく触っているNext.js 13アプリをクラウドにデプロイしていたところ
-
NEXT_PUBLIC_
変数が空になる - クラウド環境のサーバーインスタンスに該当の環境変数は設定できている
- ローカル環境では
production
ビルドで同じ環境変数名と値を設定していて問題ない
という事案に遭遇しました。
この記事では、その原因~おおまかな解決手順を記したいと思います。
前提
- Next.js 13アプリは
Dockerfile
を構成してある - GitHub ActionsでCI/CDパイプラインを構築してありNext.js 13アプリはコンテナーアプリとしてクラウドにデプロイされる
- 環境変数はCI/CDパイプライン内にてGitHubリポジトリーの
variables
/secrets
を読み込んで設定している
原因
- ビルド時ではなくデプロイ時に環境変数を設定していたため
NEXT_PUBLIC_環境変数/その他環境変数を設定すべきタイミングの違い
公式ドキュメントをちゃんと読めば書いてあったのですが(💦)、Next.js現行バージョン(13.4)ではクライアントに渡すNEXT_PUBLIC_
変数はビルド時に環境変数からJavaScriptコード内に埋め込まれるようです。そのため、CI/CDパイプラインも以下のような構成にする必要がありました。
build(NEXT_PUBLIC_
環境変数はここで設定しておく必要がある)
↓
deploy(その他環境変数はここで設定しても基本問題なし)
公式ドキュメント
おおまかな解決手順
1. workflowsからsecretsをDockerfileに渡す
以下のように、docker/build-push-action@v3
であればwith.build-args
でsecrets
をビルド引数に渡すことができます。
.github/workflows/release_example.yml
jobs:
build:
runs-on: 'ubuntu-latest'
steps:
# ...
- name: Build and push container image to registry
uses: docker/build-push-action@v3
with:
push: true
tags: examplecr/exampleuser/exampleimage:${{ github.sha }}
file: ./Dockerfile
build-args: |
"NEXT_PUBLIC_FOO=${{ secrets.NEXT_PUBLIC_FOO }}"
2. Dockerfileで.env.productionを生成する
そして以下のように、ARG
で受け取った値をビルド前に.env.production
へ書き出しておくようにします。すると、Next.js 13がビルド時にNEXT_PUBLIC_
を読み込み、クライアントに渡るJavaScriptコードにも埋め込まれるようになりました。
Dockerfile
# Create .env.production
ARG NEXT_PUBLIC_FOO
RUN touch .env.production
RUN echo "NEXT_PUBLIC_FOO=$NEXT_PUBLIC_FOO" >> .env.production
RUN cat .env.production
# Build
RUN npm run build
以上です。もしどなたかの参考になることがあれば幸いです。
Discussion