Express.js
Configuración y variables de entorno
Explica cómo cargar y validar configuración, separar entornos, gestionar secretos y evitar valores parciales o inconsistentes durante startup y tests.
- Última actualización
- Actualizada
- Nivel
- Fundamentos
Express.js
Explica cómo cargar y validar configuración, separar entornos, gestionar secretos y evitar valores parciales o inconsistentes durante startup y tests.
La configuración es input externo del proceso. Debe validarse una vez al arrancar y transformarse en un objeto explícito; process.env no es una API tipada ni segura por sí sola.
Variables de entorno llegan como strings opcionales:
process.env.PORT // string | undefinedLa aplicación necesita convertirlas en un contrato:
process.env
↓ parse + validate
AppConfig
↓
dependencias y módulosLecturas dispersas producen:
Fail fast evita que el proceso acepte tráfico con una URL o secreto inválido.
const EnvironmentSchema = z.object({
NODE_ENV: z.enum(['development', 'test', 'production']),
HOST: z.string().default('0.0.0.0'),
PORT: z.coerce.number().int().min(1).max(65_535).default(3000),
DATABASE_URL: z.string().url(),
PUBLIC_BASE_URL: z.string().url(),
LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
SESSION_SECRET: z.string().min(32),
});z.coerce es intencional para números. No conviertas booleanos con Boolean('false'), porque produce true.
No distribuyas nombres de env por toda la aplicación:
export function loadConfig(env: NodeJS.ProcessEnv): AppConfig {
const parsed = EnvironmentSchema.parse(env);
return {
runtime: {
environment: parsed.NODE_ENV,
host: parsed.HOST,
port: parsed.PORT,
},
database: {
url: parsed.DATABASE_URL,
},
http: {
publicBaseUrl: new URL(parsed.PUBLIC_BASE_URL),
},
security: {
sessionSecret: parsed.SESSION_SECRET,
},
logging: {
level: parsed.LOG_LEVEL,
},
};
}Esto separa el contrato de deployment del modelo interno.
Variables de entorno son un mecanismo de entrega, no un secret manager completo. Plataformas pueden inyectar secretos desde Vault, cloud secret manager o Kubernetes Secrets.
Reglas:
Útil en desarrollo local. No debe convertirse en fuente de verdad de producción. Mantén .env.example sin valores sensibles:
NODE_ENV=development
PORT=3000
DATABASE_URL=postgresql://...
SESSION_SECRET=Documenta propósito y formato.
Una base URL pública puede aparecer en responses. Un database URL no. Clasifica configuración para evitar serializar el objeto completo.
No expongas un endpoint /config que devuelve todos los valores.
Un flag no es simplemente un booleano eterno. Define:
Los flags no deben sustituir autorización.
Algunos valores pueden cambiar sin restart, pero añade complejidad:
La configuración estática al startup es más simple. Usa dinámica solo cuando el requisito lo justifica.
Defaults son adecuados para desarrollo o valores inocuos. Para secretos, database URL y dominios de seguridad, fallar suele ser mejor que inventar.
Un default oculto de localhost en producción puede conectar al lugar equivocado.
Evita grandes bloques:
if (NODE_ENV === 'production') ...Prefiere configuración explícita. NODE_ENV puede ajustar logging u optimización, pero no debe contener toda la lógica de producto.
Algunas reglas dependen de varios campos:
SameSite=None requiere Secure.Añade refinements después de parsear.
const config = loadConfig({
NODE_ENV: 'test',
DATABASE_URL: 'postgresql://test',
PUBLIC_BASE_URL: 'http://localhost:3000',
SESSION_SECRET: 'x'.repeat(32),
});Pasar env explícito evita mutar process.env global. Si debes mutarlo, restaura después.
Presenta nombres y razones sin valores:
{
"event": "configuration_invalid",
"fields": ["DATABASE_URL", "SESSION_SECRET"]
}El proceso debe salir con código no cero.
No hornees secretos en la imagen mediante ARG o ENV durante build. Inyéctalos al ejecutar. La misma imagen debe poder promoverse entre ambientes.
DomiSys requiere URL pública para callbacks. En vez de derivarla de Host:
PUBLIC_BASE_URL.Registra una versión segura de configuración:
Nunca secrets o connection strings completas.
process.env en cada módulo.Boolean(env.FLAG)..env como producción.Boolean('false') es incorrecto?Application factory y startup utiliza la configuración para construir el runtime en un orden controlado.