AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 79567958
Accepted
SkyN
SkyN
Asked: 2025-04-11 11:46:20 +0800 CST2025-04-11 11:46:20 +0800 CST 2025-04-11 11:46:20 +0800 CST

Nuxt 3 运行时配置在生产 Docker 构建中没有从 process.env 填充,但 process.env 稍后可用

  • 772

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 ...
  }
});

症状:

  1. 登录失败:登录处理程序抛出错误Error: secretOrPrivateKey must have a value,因为config.portalJwtSecret是一个空字符串(""),尽管它的类型被正确推断为string。
  2. 中间件看到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);
    });
    
    该中间件的日志显示:
    [Middleware log-config] JWT Secret: 
    [Middleware log-config] Type of jwtSecret: string
    [Middleware log-config] process.env.JWT_SECRET: a9d3fd7cee941559f18f43dd6c87fc39cf611a540ffbc6b4b1f5675b569af176
    
    这清楚地表明,在处理请求时在正在运行的 Node.js 环境中设置正确,但process.env.JWT_SECRET 返回useRuntimeConfig(event).jwtSecret的是空字符串。
  3. 常量工作:如果我直接将中的变量定义runtimeConfig为字符串文字(例如someConstant: 'ThisValueWorks'),则可以通过正确访问useRuntimeConfig()。
  4. nuxt dev有效:使用 进行本地运行时不会出现此问题nuxt dev;在开发模式下runtimeConfig从文件正确填充。.env
  5. 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_modulesnpm installdocker compose up --build -d --force-recreate
  • 使用不同的变量名(JWT_SECRET,PORTAL_JWT_SECRET,NUXT_PORTAL_JWT_SECRET)。
  • process.env.VAR_NAME可以通过中间件日志进行确认。

问题:

为什么在运行生产构建时,通过inuseRuntimeConfig()定义的服务器端变量会返回空字符串?如何确保在 Docker 容器中的服务器启动时使用这些环境变量正确初始化?process.envnuxt.config.ts.output/server/index.mjsruntimeConfig

nuxt.js
  • 1 1 个回答
  • 20 Views

1 个回答

  • Voted
  1. Best Answer
    Tatachiblob
    2025-04-11T18:48:35+08:002025-04-11T18:48:35+08:00

    部分答案可以在nuxt 文档中找到。我只是不知道为什么它process.env与 RuntimeConfig 在同一级别工作。

    由于您正在使用带有environment变量的 docker compose,因此您可以调整以下内容以使其config.jwtSecret可访问:

    添加NUXT_前缀。

    # docker-compose.yml
    services:
      portal:
        # ... image, build context, etc.
        environment:
          NUXT_JWT_SECRET: ${NUXT_JWT_SECRET}
          # ... other env vars
        # ... ports, depends_on, etc.
    

    Docker compose 将读取该.env文件并设置NUXT_JWT_SECRET为容器的环境变量,并与 Nuxt 的生产设置一起工作。

    您可以在我刚刚创建的 github repo 中亲自尝试。

    https://github.com/YutaInouePH/env_check

    以下是输出。

    访问 http://localhost:3000

    ↓

    $ docker compose up -d
    $ docker compose logs -f
    app-1  | Listening on http://0.0.0.0:3000
    app-1  | Frontned:  mysecret 2025-04-11T10:41:53.944Z
    app-1  | JWT Secret value INSIDE server side: mysecret
    app-1  | Type of portalJwtSecret: string
    

    浏览器输出

    • 1

相关问题

  • Nuxt 服务器中的路由和 api 功能有什么区别?[关闭]

  • 容器的 Tailwind 填充设置

  • 同时使用 FB Pixel 和 GTM

  • 翻译信息不能包含字符串化的 json

  • 在Nuxt 3项目中放置一个单独的子项目

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    重新格式化数字,在固定位置插入分隔符

    • 6 个回答
  • Marko Smith

    为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会?

    • 2 个回答
  • Marko Smith

    VScode 自动卸载扩展的问题(Material 主题)

    • 2 个回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Martin Hope
    Fantastic Mr Fox msvc std::vector 实现中仅不接受可复制类型 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant 使用 chrono 查找下一个工作日 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor 构造函数的成员初始化程序可以包含另一个成员的初始化吗? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský 为什么 C++20 概念会导致循环约束错误,而老式的 SFINAE 不会? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul C++20 是否进行了更改,允许从已知绑定数组“type(&)[N]”转换为未知绑定数组“type(&)[]”? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann 为什么 {2,3,10} 和 {x,3,10} (x=2) 的顺序不同? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve