背景
试了半天儿的 nextjs config 配置 env、publicRuntimeConfig、ServerRuntimeConfig
都只能在 Docker 构建时注入环境变量,全网愣是没搜到怎么在 Docker 容器运行时从配置的环境变量初始化配置信息
构建时注入会导致无法满足 “一次构建,多环境运行” 的期望,比较浪费流水线和服务器构建资源,一定程度上影响了部署时效和项目实施进度,浪费时间和精力
解决方法
- 准备
.env.tpl模板文件,文件内容:
BASE_PATH=${BASE_PATH}
dockerfile在CMD容器运行服务的命令前,通过envsubst命令将环境变量通过.env.tpl模板生成next可用的环境变量文件.env
CMD ["/bin/sh", "-c", "envsubst < /app/public/.env.tpl > /app/.env && npm start"]
- 服务端在最外层 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>
)
}
- 这样,在浏览器环境就可以这样使用
const config = window.__initState__
- 为了简便使用,统一放在
config.ts文件导出使用
let config: { basePath: string } // 类型封出去哈
if (typeof window === 'undefined'){
config = {
basePath: process.env.BASE_PATH
}
} else {
config = window.__initState__
}
export default config