Aplicações precisam de valores que mudam entre desenvolvimento, testes e produção: porta, URL do banco, nível de log, chaves de API e flags. As variáveis de ambiente no Node.js permitem fornecer essas configurações sem alterar o código-fonte.
Embora process.env seja simples, todos os valores chegam como strings ou ficam ausentes. Um booleano com texto false continua sendo uma string verdadeira em condições JavaScript. Além disso, espalhar leituras por todo o projeto dificulta validação, testes e rotação de segredos.
Neste guia, você aprenderá a ler variáveis, usar arquivos .env, validar e converter tipos, separar configuração de segredo, evitar vazamentos e organizar ambientes de produção.
Lendo process.env
const port = process.env.PORT || '3000';
console.log(`Servidor na porta ${port}`);O objeto process.env contém as variáveis disponíveis ao processo. A documentação oficial de process.env descreve seu comportamento. Versões atuais também possuem recursos nativos para arquivos de ambiente, documentados em Environment Variables.
Para revisar a plataforma, consulte o que é Node.js e o que é JavaScript.
Definindo variável no terminal
Em sistemas Unix:
PORT=4000 NODE_ENV=production node server.jsNo PowerShell:
$env:PORT="4000"
node server.jsScripts npm podem usar ferramentas multiplataforma quando precisam definir valores da mesma maneira em Windows, Linux e macOS.
Arquivos .env
PORT=3000
DATABASE_URL=postgresql://localhost/app
LOG_LEVEL=infoUm arquivo .env facilita desenvolvimento local. Em versões que suportam o recurso:
node --env-file=.env server.jsTambém é possível usar bibliotecas conhecidas. Confirme precedência entre variáveis já definidas e valores do arquivo.
Não versione segredos
Adicione arquivos locais sensíveis ao .gitignore:
.env
.env.local
.env.*.localPublique apenas um .env.example sem valores reais:
PORT=3000
DATABASE_URL=
API_KEY=
Se um segredo foi enviado ao Git, removê-lo do arquivo atual não basta. Revogue e gere outro, pois o valor permanece no histórico e em clones.
Centralizando configuração
function requireEnv(name) {
const value = process.env[name];
if (!value) {
throw new Error(`Variável obrigatória ausente: ${name}`);
}
return value;
}
const config = Object.freeze({
port: Number(process.env.PORT || 3000),
databaseUrl: requireEnv('DATABASE_URL'),
nodeEnv: process.env.NODE_ENV || 'development'
});
module.exports = config;Carregue e valide uma vez durante a inicialização. O restante da aplicação recebe um objeto consistente.
Convertendo números
function parseInteger(name, fallback) {
const raw = process.env[name];
if (raw === undefined) return fallback;
const value = Number(raw);
if (!Number.isInteger(value)) {
throw new Error(`${name} deve ser inteiro`);
}
return value;
}Valide faixa:
const port = parseInteger('PORT', 3000);
if (port < 1 || port > 65535) {
throw new Error('PORT fora da faixa');
}Convertendo booleanos
function parseBoolean(name, fallback = false) {
const raw = process.env[name];
if (raw === undefined) return fallback;
if (raw === 'true') return true;
if (raw === 'false') return false;
throw new Error(`${name} deve ser true ou false`);
}Não use Boolean(process.env.FEATURE_ENABLED), pois Boolean('false') resulta em verdadeiro.
Listas e JSON
const origins = (process.env.CORS_ORIGINS || '')
.split(',')
.map(value => value.trim())
.filter(Boolean);Para estruturas grandes, uma variável JSON fica difícil de manter. Prefira arquivo de configuração, serviço de configuração ou banco, conforme a necessidade.
Validação com schema
Bibliotecas de schema tornam erros mais claros:
const { z } = require('zod');
const schema = z.object({
PORT: z.coerce.number().int().min(1).max(65535),
DATABASE_URL: z.string().url(),
NODE_ENV: z.enum(['development', 'test', 'production'])
});
const env = schema.parse(process.env);Veja Zod no TypeScript para validação detalhada.
Falhar cedo
Se uma variável obrigatória está ausente, encerre a inicialização antes de aceitar tráfego. Descobrir a falha apenas na primeira requisição produz indisponibilidade parcial e diagnóstico difícil.
NODE_ENV
NODE_ENV é uma convenção, não uma variável mágica universal. Bibliotecas podem alterar comportamento com base nela. Use valores consistentes e não misture ambiente com região, cliente ou função da instância.
Configuração não é segredo
Porta e nível de log são configurações. Senhas, tokens e chaves são segredos. Ambos podem chegar por ambiente, mas segredos exigem controle de acesso, rotação, auditoria e proteção adicional.
Secret managers
Em produção, use recursos da plataforma, como secret manager, KMS ou arquivos montados. Variáveis de ambiente podem aparecer em dumps, ferramentas administrativas e configurações de deploy. Avalie o modelo de ameaça.
Para criptografia e chaves, consulte Crypto no Node.js.
Não registre process.env
console.log(process.env);Essa prática pode enviar credenciais a logs. Registre apenas nomes de configurações não sensíveis e valores mascarados quando necessário.
Redação de logs
logger.info({
nodeEnv: config.nodeEnv,
port: config.port,
databaseConfigured: Boolean(config.databaseUrl)
}, 'Configuração carregada');Não registre a URL completa do banco se ela contém senha.
Testes
Evite módulos que capturam variáveis antes do teste conseguir configurá-las. Exporte uma função:
function loadConfig(env = process.env) {
return {
port: Number(env.PORT || 3000),
mode: env.NODE_ENV || 'development'
};
}
module.exports = { loadConfig };test('usa porta informada', () => {
const config = loadConfig({ PORT: '4000' });
assert.equal(config.port, 4000);
});O Node Test Runner ajuda a isolar cenários.
Processos filhos
Ao criar outro processo, controle quais variáveis são herdadas:
spawn(process.execPath, ['worker.js'], {
env: {
NODE_ENV: config.nodeEnv,
WORKER_QUEUE: 'emails',
PATH: process.env.PATH
}
});Não envie todos os segredos automaticamente. Veja Child Process no Node.js.
Contêineres
Em Docker e orquestradores, valores podem ser injetados por configuração ou segredo. Não grave arquivos .env reais na imagem. A mesma imagem deve funcionar em vários ambientes com parâmetros externos.
Rotação
Variáveis são normalmente lidas na inicialização. Ao trocar um segredo, talvez seja necessário reiniciar instâncias gradualmente. Para rotação sem reinício, use um cliente de secret manager e cache controlado.
Flags de funcionalidade
Variáveis funcionam para flags simples de deploy. Para mudanças frequentes, segmentação por usuário e auditoria, use um sistema de feature flags. Reiniciar todo o serviço para cada mudança pode ser inadequado.
Tamanho e portabilidade
Sistemas operacionais impõem limites ao ambiente do processo. Não armazene certificados enormes, documentos ou configurações complexas sem avaliar. Arquivos montados podem ser mais adequados.
Erros comuns
- Tratar toda variável como string pronta para uso.
- Usar
Boolean('false'). - Versionar arquivo com segredos.
- Ler variáveis em todos os módulos.
- Não validar na inicialização.
- Registrar
process.env. - Herdar segredos em processos que não precisam.
- Alterar variável esperando que módulos já carregados atualizem.
Boas práticas
- Centralize e valide configuração.
- Converta tipos explicitamente.
- Falhe cedo para valores obrigatórios.
- Use
.env.examplesem segredos. - Prefira secret manager em produção.
- Não registre valores sensíveis.
- Separe configuração de segredo.
- Injete apenas variáveis necessárias em processos filhos.
- Planeje rotação e reinício gradual.
- Teste combinações inválidas.
Conclusão
As variáveis de ambiente no Node.js separam configuração do código e permitem usar o mesmo artefato em vários ambientes. process.env, arquivos .env e recursos da plataforma fornecem os valores durante a inicialização.
O padrão confiável é centralizar, validar e converter. Segredos precisam de rotação e controle de acesso, enquanto logs devem revelar apenas o necessário. Com um objeto de configuração imutável, a aplicação fica mais previsível e fácil de testar.




