runtimeConfig
我遇到一个问题:在 Docker Compose 管理的 Docker 容器中运行生产构建时,Nuxt 3 中的服务器端无法从环境变量正确填充。但是,process.env
在请求期间直接在服务器中间件内访问时,我可以看到正确的值。
设置:
- Nuxt: v3
- 节点: v20
- 构建流程:
npm run build
Docker 多阶段构建的标准流程。最后阶段运行CMD ["node", ".output/server/index.mjs"]
。
问题:
在我的中nuxt.config.ts
,我定义了一个服务器端运行时配置变量,旨在从环境变量中加载:
// nuxt.config.ts
export default defineNuxtConfig({
// ...
runtimeConfig: {
// This should be populated from the environment variable
jwtSecret: process.env.JWT_SECRET,
// ...
},
// ...
})
我的.env
文件(由 Docker Compose 使用)定义了变量:
# .env file
JWT_SECRET=a9d3fd7cee941559f18f43dd6c87fc39cf611a540ffbc6b4b1f5675b569af176
# ... other vars
我docker-compose.yml
将此变量传递给portal
服务:
# docker-compose.yml
services:
portal:
# ... image, build context, etc.
environment:
JWT_SECRET: ${JWT_SECRET}
# ... other env vars
# ... ports, depends_on, etc.
当我运行 API 路由(例如/api/auth/login.post.ts
)时,代码会尝试访问秘密:
// server/api/auth/login.post.ts (simplified)
import { defineEventHandler, useRuntimeConfig } from 'h3';
import jwt from 'jsonwebtoken';
export default defineEventHandler(async (event) => {
const config = useRuntimeConfig(event);
const secret = config.jwtSecret;
console.log('JWT Secret value INSIDE login handler:', secret);
console.log('Type of portalJwtSecret:', typeof secret);
try {
// ... authentication logic ...
// This line throws the error because 'secret' is an empty string
const token = jwt.sign({ userId: user.id }, secret, { expiresIn: '7d' });
// ... return token ...
} catch (error) {
console.error('Login error:', error);
// ... handle error ...
}
});
症状:
- 登录失败:登录处理程序抛出错误
Error: secretOrPrivateKey must have a value
,因为config.portalJwtSecret
是一个空字符串(""
),尽管它的类型被正确推断为string
。 - 中间件看到
process.env
:我添加了一个服务器中间件(server/middleware/log-config.ts
)来检查请求期间的值:
该中间件的日志显示:// server/middleware/log-config.ts import { defineEventHandler, useRuntimeConfig } from 'h3'; export default defineEventHandler((event) => { const config = useRuntimeConfig(event); console.log('[Middleware log-config] JWT Secret:', config.jwtSecret); console.log('[Middleware log-config] Type of portalJwtSecret:', typeof config.jwtSecret); console.log('[Middleware log-config] process.env.JWT_SECRET:', process.env.JWT_SECRET); });
这清楚地表明,在处理请求时在正在运行的 Node.js 环境中设置正确,但[Middleware log-config] JWT Secret: [Middleware log-config] Type of jwtSecret: string [Middleware log-config] process.env.JWT_SECRET: a9d3fd7cee941559f18f43dd6c87fc39cf611a540ffbc6b4b1f5675b569af176
process.env.JWT_SECRET
返回useRuntimeConfig(event).jwtSecret
的是空字符串。 - 常量工作:如果我直接将中的变量定义
runtimeConfig
为字符串文字(例如someConstant: 'ThisValueWorks'
),则可以通过正确访问useRuntimeConfig()
。 nuxt dev
有效:使用 进行本地运行时不会出现此问题nuxt dev
;在开发模式下runtimeConfig
从文件正确填充。.env
NUXT_
前缀失败:我也尝试在环境变量前添加前缀NUXT_
(例如NUXT_JWT_SECRET
),希望能够自动填充,但结果useRuntimeConfig().jwtSecret
却是undefined
那样。
我尝试过的方法:
- 确保文件中的值周围没有引号
.env
。 - 验证变量名称在
.env
、docker-compose.yml
和 中是否完全匹配nuxt.config.ts
。 - 检查覆盖
docker-compose.override.yml
(未找到)。 - 停止容器(
docker compose down
)、移除.nuxt
、、、运行和重建(.output
)。node_modules
npm install
docker compose up --build -d --force-recreate
- 使用不同的变量名(
JWT_SECRET
,PORTAL_JWT_SECRET
,NUXT_PORTAL_JWT_SECRET
)。 process.env.VAR_NAME
可以通过中间件日志进行确认。
问题:
为什么在运行生产构建时,通过inuseRuntimeConfig()
定义的服务器端变量会返回空字符串?如何确保在 Docker 容器中的服务器启动时使用这些环境变量正确初始化?process.env
nuxt.config.ts
.output/server/index.mjs
runtimeConfig