NextJS - 如何获取运行时环境变量

20

新手问题,敬请谅解。

我想知道是否有人知道NextJS自托管(例如docker或kubernetes)的推荐部署流程。我正在执行典型的“构建一次,在每个环境中进行发布”操作,同时更改环境变量以匹配环境,但保持镜像相同。

由于在使用“getInitialProps”和“publicRuntimeConfig”时,NextJS会自动退出SSG,因此我想知道,将相同的镜像部署到多个环境(再次自托管在通用云中,例如docker run)的最佳方法是什么。

  1. 我是否必须始终嵌入环境变量?这样我就必须为每个环境构建一个镜像,并针对环境变量的每次更新进行构建。
  2. 使用publicRuntimeConfig / getInitialProps,但忽略SSG优化,即使我的变量不含机密信息(例如GA_TRACKING_ID)。
  3. ...还有其他什么办法吗?

感谢您的帮助!


1
我也在想同样的问题。也许在next.config.js中尝试dotenv是值得的。 - Michael Czolko
4个回答

3

您可能想要查看react-env,它可以做到这一点。

其思想是,react-env将为您生成一个包含环境变量的__ENV.js JS文件,您可以通过window或env助手在客户端访问它们,例如:

<small>
  Works in the browser: <b>{env("CRA")}</b>.
</small>

使用Docker时,您可以设置一个入口点来生成所需的__ENV.js,当容器启动时:(参考链接)
ENTRYPOINT yarn react-env --env APP_ENV

服务器端变量怎么办? - JorgeeFG
你可能想要检查@iamkirill的答案 https://dev59.com/QlEG5IYBdhLWcg3weOoT#74246133 - Gyum Fox
我最近也遇到了import-met-env,它似乎可以达到相同的目的,并且还可以在服务器端使用。我还没有尝试过,但你应该看一下。 - Gyum Fox

2

我将在@gyum-fox的答案基础上进行扩展,因为react-env文档不是最新的,有些事情需要花费一些时间来弄清楚。

Next.js版本:12.2.5

软件包

react-env Next.js repo中使用了2个软件包:react-env@beam-australia/react-env。我不知道前者的目的,我使用了后者。

"同构"

react-env声称它是同构的,但我无法使其在服务器端工作。因此,需要更改.env文件。

REGULAR_VAR=VALUE
NEXT_PUBLIC_REGULAR_VAR=$REGULAR_VAR

我在服务器和客户端都使用了一些变量,为了使其工作:

  • REGULAR_VAR 用于服务器中,在 .env 文件中管理
  • NEXT_PUBLIC_REGULAR_VAR 在客户端中像这样使用:env('REGULAR_VAR')(注意:前缀NEXT_PUBLIC被移除)。在__ENV.js文件中管理

使用该包

要在 Next.js 中使用__ENV.js 文件,请将以下行放置在 _document.tsx

<Script src="/__ENV.js" strategy="beforeInteractive" />

注意:虽然__ENV.js位于/public目录中,但在运行时文件将位于根目录下,因为该目录中的每个文件都将如此。

生成__ENV.js文件

react-env命令只需要用来生成__ENV.js文件,以便您可以启动项目:

# like this
npx react-env --prefix NEXT_PUBLIC -- node server.js
# or like this
yarn react-env --prefix NEXT_PUBLIC && node server.js
  • --prefix NEXT_PUBLIC:客户端环境变量的默认值为NEXT_PUBLIC
  • node server.js:或者next dev或任何其他启动项目的命令

Docker

我使用来自Vercel示例的Dockerfile进行部署。 要在容器中生成__ENV.js文件,请更改

RUN yarn build

RUN npx react-env --prefix NEXT_PUBLIC --path .env.production -- yarn build

在这里,我添加了--path .env.production以使用生产环境变量。

结论

就是这样!现在您可以在__ENV.js中更改客户端环境变量,重新启动生产服务器,新值将被应用。


1
@beam-australia/react-env 的替代方案:https://github.com/expatfile/next-runtime-env(类似的方法) - Michael Johansen

2
我已经实现了一个库,它可以做任何事情,包括热环境重新加载等等。 运行得非常好,我们开始使用它来简化我们项目的持续集成/持续交付和秘密存储。

https://www.npmjs.com/package/@cuww/runtime-env


-1

一种不太优化的解决方案是在容器运行时构建下一个项目,这样您就可以在运行时读取环境变量。

这种方法至少有两个明显的缺点:

  • 启动速度较慢
  • 镜像大小较大

带有运行时构建的Dockerfile示例:

FROM node:18-alpine

WORKDIR /app

ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1

COPY ./public public
COPY ./src src
COPY .env.local .env.local
COPY next.config.js next.config.js
COPY package.json package.json
COPY tsconfig.json tsconfig.json
COPY node_modules node_modules

# Create and give access to folders and files that will be edited during build time
RUN mkdir -p .next
RUN touch next-env.d.ts

RUN chmod -R ugo+rwX .next next-env.d.ts

USER 1001

EXPOSE 8080
ENV PORT=8080

ENTRYPOINT ["/bin/sh", "-c", "npm run build && npm run start"]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接