【化蛹为蝶】NextJs 获取 Docker 运行时环境变量,初始化配置在 Server/Client 时使用

809 阅读1分钟

背景

试了半天儿的 nextjs config 配置 envpublicRuntimeConfigServerRuntimeConfig

都只能在 Docker 构建时注入环境变量,全网愣是没搜到怎么在 Docker 容器运行时从配置的环境变量初始化配置信息

构建时注入会导致无法满足 “一次构建,多环境运行” 的期望,比较浪费流水线和服务器构建资源,一定程度上影响了部署时效和项目实施进度,浪费时间和精力

解决方法

  1. 准备 .env.tpl 模板文件,文件内容:
BASE_PATH=${BASE_PATH}
  1. dockerfileCMD 容器运行服务的命令前,通过 envsubst 命令将环境变量通过 .env.tpl 模板生成 next 可用的环境变量文件 .env
CMD ["/bin/sh",  "-c",  "envsubst < /app/public/.env.tpl > /app/.env && npm start"]
  1. 服务端在最外层 Layout 时从环境变量里读取配置信息,并注入在前端
// 在服务端 node 上下文执行
const config = { basePath: process.env.BASE_PATH }

const RootLayout = () => {
    return (
        <html>
            <Script id="initState" strategy="beforeInteractive">
              {`window.__initState__=${JSON.stringify(config)}`}
            </Script>
        </html>
    )
}
  1. 这样,在浏览器环境就可以这样使用
const config = window.__initState__
  1. 为了简便使用,统一放在 config.ts 文件导出使用
let config: { basePath: string }  // 类型封出去哈

if (typeof window === 'undefined'){
    config = {
        basePath: process.env.BASE_PATH
    }
} else {
    config = window.__initState__
}

export default config

简易流程图

image.png