Open12

Next.jsと環境変数メモ

inomotoinomoto

ごく普通にサーバ起動したNext.jsで環境変数を読みたいだけだが、異常に難しい。
というわけでメモ

inomotoinomoto

前提

  • Next.js 13.4.13 App Router
  • standalone mode
  • CloudRunを想定しているが、基本的にローカルでテストしている
inomotoinomoto

公式にわかりやすく存在するドキュメント
https://nextjs.org/docs/app/building-your-application/configuring/environment-variables

.env.hoge ファイルを置くとprocess.envに展開されるとのこと。
また環境変数名としてNEXT_PUBLIC_ prefixすると、ブラウザ側も含めてprocess.envから?読めるようになるらしい。

ただ常識的に考えてサーバサイドプロセスに環境変数に渡すのはcredentialであり、Dockerイメージに残る.envファイルもブラウザに展開されるNEXT_PUBLIC_も選択肢になり得ない。

inomotoinomoto

.envファイル方式については、ビルドタイムでもランタイムでも動いた。なおstandalone modeではランタイムはダメ。

inomotoinomoto

いやstandalone modeでも、.next/standalone/.envにファイルを置いたら認識された。
ちなみにビルド時にcwdに.envがあると、そのファイルが上記パスにコピーされるっぽい。

inomotoinomoto

これテストは↓のexport const dynamic = 'force-dynamic'なので、なんか色々条件は整理しないとダメそう

inomotoinomoto

force-dynamicとかなくてもAPIルートなら(POSTなら?).envで読めるっぽい

inomotoinomoto

リポジトリにdiscussionが立っており、みんな困っている。それはそう。
https://github.com/vercel/next.js/discussions/44628

色々ハックがあるが(いや普通の方法無いのかよ...)、App Routerでは使えないものが多いとの話。

そんな中、下記はApp Routerでも使えるとのこと。
https://github.com/vercel/next.js/discussions/44628#discussioncomment-7040424

RootLayoutのファイルで export const dynamic = 'force-dynamic' を指定するとよいらしい。
なおdynamicとかなんとかのドキュメント
https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config

そしてこの方法は実際に動く。ただしstandalone modeでは動かなかった。

inomotoinomoto

てかstandaloneじゃない場合 & API POSTのルートならごく普通に読めた。

inomotoinomoto

おそらく

  • process.envが読める状態であること
    • not standaloneで、プロセスに環境変数が渡されている or .envがある(などなど)
    • standalone modeで、.envがある
  • 処理をしているページが動的モード?になっていること
    • force-dynamicなどになっている
    • APIルート and/or POSTなど

であれば読めるのであろう。後者が成立しない場合、ビルドタイムにprocess.env記述自体が書き換えられてしまう。

inomotoinomoto

いまのところ、standaloneモードを捨てるか、コンテナのinit時にnode起動前に.envファイルを生成する処理を仕込むしかなさそう。

inomotoinomoto

update: Next14にしたところ、standaloneモードでも普通の環境変数が普通に読めるようになっていた