Cloud Run, Amplify, Netlify, Vercel上のNext.js環境変数事情
前の記事で環境を複数にしたのでログをNewRelicに集めようとしたら環境変数が素直に渡らないことがあったので実験しました。
## 検証したいこと
以下の2点です。
- .envファイル、next.config.js、Vercel等の設定画面の設定値はどれが勝つのか?
- middleware、サーバー、クライアントでどの環境変数が使えるのか?
## 検証方法
以下のラインナップで環境変数を設定します。説明のためVercelを例にします。
- Xenv .envファイルでの設定値
- Xconf next.config.jsでの設定値
- Xhost Vercelの設定画面での設定値 (サービス名に合わせます)
環境変数 ※1 | 観点 | |||
---|---|---|---|---|
EVTEST_ENV | E | どこで使えるか | ||
EVTEST_CNF | C | どこで使えるか | ||
EVTEST_HST | H | どこで使えるか | ||
EVTEST_ENV_CNF | E | C | どちらの値が見えるのか | |
EVTEST_ENV_HST | E | H | どちらの値が見えるのか | |
EVTEST_CNF_HST | C | H | どちらの値が見えるのか |
※1 NEXT_PUBLIC_EVTEST_ENV
のように NEXT_PUBLIC_
をつけたものも用意します。
値の設定方法
### .envファイルでの設定
### next.config.js (next.config.ts) での設定
### Vercelの設定画面での設定
### Cloud Runの設定画面での設定
### Amplifyの設定画面での設定
### Netlifyの設定画面での設定
(Xenv,Xconf,Xhost) の設定に対して、以下のタイミングで値を確認します。
- Ymid Middleware処理時
- Yssr このページのSSR処理時
- Yroute /2024/nextjs-env/api/route.ts の処理時
- Yclient このページのクライアント処理時
値の確認方法
まず以下の関数を用意しました。
### Middleware処理時
middleware.tsで /envtest へのリクエストに上記関数の結果を返すようにします。このページでの結果は以下の通りです。
### このページのSSR処理時
SSRなコンポーネントで上記関数の結果を返すようにします。
EnvTestData
はEVTEST_ENV=env
のように変数名とその値を1行ずつ出力します。このページでの結果は以下の通りです。
EVTEST_ENV=E EVTEST_CNF=C EVTEST_HST= EVTEST_ENV_CNF=C EVTEST_ENV_HST=E EVTEST_CNF_HST=C NEXT_PUBLIC_EVTEST_ENV=E NEXT_PUBLIC_EVTEST_CNF=C NEXT_PUBLIC_EVTEST_HST= NEXT_PUBLIC_EVTEST_ENV_CNF=C NEXT_PUBLIC_EVTEST_ENV_HST=E NEXT_PUBLIC_EVTEST_CNF_HST=C EVTEST_ENV2=E EVTEST_CNF2= EVTEST_HST2= EVTEST_ENV_CNF2=E EVTEST_ENV_HST2=E EVTEST_CNF_HST2= NEXT_PUBLIC_EVTEST_ENV2=E NEXT_PUBLIC_EVTEST_CNF2= NEXT_PUBLIC_EVTEST_HST2= NEXT_PUBLIC_EVTEST_ENV_CNF2=E NEXT_PUBLIC_EVTEST_ENV_HST2=E NEXT_PUBLIC_EVTEST_CNF_HST2=
### /2024/nextjs-env/api/route.ts の処理時
SSRと同じ結果と予想したのですが、念のため用意しました。
このページでの結果は以下の通りです。
### このページのクライアント処理時
EnvTestSsr.tsx を "use client" にしたものです。Hydrationを避けるためuseEffect内で値を取得しています。
このページでの結果は以下の通りです。
## 2024年12月15日の結果
public は NEXT_PUBLIC_
をつけた場合です。後半は next.config.js
で中継した場合です。
Xenv
Xconf
Xhost
Ymid
Yssr
Yroute
Yclient
- .envで設定した環境変数はどこで使えるのか (1, 7, 13, 19行目)
- サーバーで使える。
NEXT_PUBLIC_
がついていればクライアントでも使える。 - Cloud RunとAmplifyではMiddlewareでも使える。
- VercelとNetlifyのMiddlewareでは使えない。
NEXT_PUBLIC_
がついていれば使える。
- サーバーで使える。
- next.config.jsで設定した環境変数はどこで使えるのか (2, 8, 14, 20行目)
- どこでも使える。
NEXT_PUBLIC_
がついていなくてもクライアントで使える。
- どこでも使える。
- Cloud Runで設定した環境変数はどこで使えるのか (3, 9行目)
- middlewareとrouteで使える。
NEXT_PUBLIC_
がついていてもクライアントでは使えない。
- middlewareとrouteで使える。
- Amplifyで設定した環境変数はどこで使えるのか (3, 9行目)
- SSR時に使える。
NEXT_PUBLIC_
がついていれば使える。 - next.config.jsで中継するとどこでも使える。
- SSR時に使える。
- Netlify, Vercelで設定した環境変数はどこで使えるのか (3, 9行目)
- クライアント以外で使える。
NEXT_PUBLIC_
がついていればクライアントでも使える。
- クライアント以外で使える。
- Xenv と Xconf と Xhostの環境設定変数の優先順位
- (Xenv,Xconf) は Xconf が勝つ。(4行目)
- (Xenv,Xhost) は ... 5行目を見てください。
- (Xconf,Xhost) は Xconf が勝つ。(6行目)
- next.config.js で中継するとどうなるか (13-24行目)
- Cloud Runでは.envにある値以外は中継されず、既存の値も隠れてしまう。中継しない方がいい。
- Amplify, Netlify, Vercelでは中継される。クライアントでも使える。
## このページでの結果まとめ
JSON
{ "Ymiddle": ",,,,,,,,,,,,,,,,,,,,,,,", "Yserver": ",,,,,,,,,,,,,,,,,,,,,,,", "Yroute": ",,,,,,,,,,,,,,,,,,,,,,,", "Yclient": ",,,,,,,,,,,,,,,,,,,,,,," }
以上です。MiddlewareからOpenTelemetryでログを送るところはまた別の記事で書きます。