Estou enfrentando um problema em que meu servidor runtimeConfig
no Nuxt 3 não está sendo preenchido corretamente com variáveis de ambiente ao executar a compilação de produção dentro de um contêiner Docker gerenciado pelo Docker Compose. No entanto, consigo ver o valor correto ao acessar process.env
diretamente no middleware do servidor durante uma solicitação.
Configurar:
- Nuxt: v3
- Nó: v20
- Processo de compilação: Padrão
npm run build
dentro de uma compilação multiestágios do Docker. A etapa final é executadaCMD ["node", ".output/server/index.mjs"]
.
Problema:
No meu nuxt.config.ts
, defino uma variável de configuração de tempo de execução do lado do servidor que deve ser carregada de uma variável de ambiente:
// nuxt.config.ts
export default defineNuxtConfig({
// ...
runtimeConfig: {
// This should be populated from the environment variable
jwtSecret: process.env.JWT_SECRET,
// ...
},
// ...
})
Meu .env
arquivo (usado pelo Docker Compose) define a variável:
# .env file
JWT_SECRET=a9d3fd7cee941559f18f43dd6c87fc39cf611a540ffbc6b4b1f5675b569af176
# ... other vars
Meu docker-compose.yml
passa esta variável para o portal
serviço:
# docker-compose.yml
services:
portal:
# ... image, build context, etc.
environment:
JWT_SECRET: ${JWT_SECRET}
# ... other env vars
# ... ports, depends_on, etc.
Quando executo uma rota de API (por exemplo, /api/auth/login.post.ts
), o código tenta acessar o segredo:
// 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 ...
}
});
Sintomas:
- Falha no login: O manipulador de login gera
Error: secretOrPrivateKey must have a value
porqueconfig.portalJwtSecret
é uma string vazia (""
), embora seu tipo seja inferido corretamente comostring
. - Middleware Vê
process.env
: Adicionei um middleware de servidor (server/middleware/log-config.ts
) para verificar os valores durante uma solicitação:
Os logs deste middleware mostram:// 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); });
Isso mostra claramente que[Middleware log-config] JWT Secret: [Middleware log-config] Type of jwtSecret: string [Middleware log-config] process.env.JWT_SECRET: a9d3fd7cee941559f18f43dd6c87fc39cf611a540ffbc6b4b1f5675b569af176
process.env.JWT_SECRET
está definido corretamente no ambiente Node.js em execução quando a solicitação é manipulada, masuseRuntimeConfig(event).jwtSecret
está retornando uma string vazia. - Constantes Funcionam: Se eu definir uma variável
runtimeConfig
diretamente como uma string literal (por exemplo,someConstant: 'ThisValueWorks'
), ela será corretamente acessível viauseRuntimeConfig()
. nuxt dev
Funciona: Esse problema não ocorre quando executado localmente comnuxt dev
;runtimeConfig
é preenchido corretamente a partir do.env
arquivo no modo de desenvolvimento.NUXT_
Falha no prefixo: Também tentei prefixar a variável de ambiente comNUXT_
(por exemplo,NUXT_JWT_SECRET
) esperando preenchimento automático, masuseRuntimeConfig().jwtSecret
não foiundefined
o caso.
O que eu tentei:
- Garantindo que não haja aspas em torno do valor no
.env
arquivo. - Verificar se o nome da variável corresponde exatamente em
.env
,docker-compose.yml
, enuxt.config.ts
. - Verificando substituições em
docker-compose.override.yml
(nenhuma encontrada). - Parando contêineres (
docker compose down
), removendo.nuxt
,.output
,node_modules
, executandonpm install
e reconstruindo (docker compose up --build -d --force-recreate
). - Usando nomes de variáveis diferentes (
JWT_SECRET
,PORTAL_JWT_SECRET
,NUXT_PORTAL_JWT_SECRET
). - A confirmação
process.env.VAR_NAME
pode ser acessada por meio de logs de middleware.
Pergunta:
Por que useRuntimeConfig()
retornar uma string vazia para variáveis do lado do servidor é definido via process.env
in nuxt.config.ts
ao executar a compilação de produção ( .output/server/index.mjs
)? Como posso garantir runtimeConfig
que a inicialização com essas variáveis de ambiente seja feita corretamente na inicialização do servidor dentro do contêiner do Docker?