Variáveis de ambiente em Node.js: .env e segurança
Variáveis de ambiente são o mecanismo padrão para separar configuração de código — conexão ao banco, chaves de API e segredos nunca devem estar no código-fonte. Em Node.js, o dotenv carrega o arquivo .env em desenvolvimento; em produção na VPS, as variáveis vêm do docker-compose.yml ou do sistema operacional.
dotenv: carregando .env em desenvolvimento
dotenv é o pacote padrão para carregar variáveis de ambiente de um arquivo .env:
# Instalar dotenv
npm install dotenv
# Carregar o mais cedo possível (primeiro import da aplicação)
# src/index.ts ou src/index.js
import 'dotenv/config' // ESM
// ou
require('dotenv').config() // CJS
// .env (nunca commitado no git)
DATABASE_URL=postgresql://user:pass@localhost:5432/db
JWT_SECRET=minha_chave_secreta_muito_longa_e_aleatória
PORT=3000
NODE_ENV=development
# .env.example (commitado — documenta as variáveis necessárias)
DATABASE_URL=
JWT_SECRET=
PORT=3000
NODE_ENV=developmentValidar variáveis de ambiente com Zod
Falhar no startup por variável ausente é melhor que falhar em runtime com erro críptico. Zod valida e tipifica todas as variáveis na inicialização:
// src/env.ts
import { z } from 'zod'
const envSchema = z.object({
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
PORT: z.coerce.number().default(3000),
DATABASE_URL: z.string().url(),
JWT_SECRET: z.string().min(32, 'JWT_SECRET deve ter ao menos 32 caracteres'),
REDIS_URL: z.string().url().optional(),
LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
})
// Validar imediatamente — lança erro no startup se inválido
export const env = envSchema.parse(process.env)
// Uso:
import { env } from './env'
console.log(env.PORT) // number (tipado)
console.log(env.DATABASE_URL) // string (garantida válida)Variáveis de ambiente em produção (Docker)
Em produção com Docker, as variáveis vêm do docker-compose.yml ou de um arquivo .env do Compose — nunca de um .env dentro da imagem:
# docker-compose.yml
services:
app:
image: minha-api:latest
env_file:
- .env.production # arquivo .env no host (não na imagem)
environment:
NODE_ENV: production # override de variável específica
# .env.production (no host da VPS, não commitado)
DATABASE_URL=postgresql://user:pass@postgres:5432/db
JWT_SECRET=chave_longa_gerada_com_openssl_rand_hex_32
PORT=3000
# Verificar variáveis resolvidas antes de subir
docker compose config | grep -A5 "environment:"
# Injetar variável sem arquivo (útil em CI/CD)
JWT_SECRET=abc123 docker compose up -dGerar segredos seguros
Chaves JWT, session secrets e API keys devem ser geradas de forma criptograficamente segura:
# Gerar chave aleatória de 64 caracteres hex (128 bits)
openssl rand -hex 32
# Para JWT secret (256 bits)
openssl rand -base64 64
# No Node.js
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Para UUID como secret (não ideal mas funcional)
node -e "console.log(require('crypto').randomUUID())"
# Exemplo de .env com chaves geradas:
JWT_SECRET=a3f8b2c9d4e7f1a0b3c6d9e2f5a8b1c4d7e0f3a6b9c2d5e8f1a4b7c0d3e6f9a2
SESSION_SECRET=K+5J8mN2pQ7rT0vX3yB6eH9kL1nP4sV7wY0zC3fG6hJ9mO2qR5uW8xA1dF4iI7lNDiferentes ambientes: dev, staging, produção
Organize variáveis por ambiente com arquivos separados:
# Estrutura de arquivos de ambiente
.env # desenvolvimento local (não commitado)
.env.example # template (commitado — sem valores)
.env.test # testes automatizados (pode ter valores fake)
# .gitignore — garantir que .env nunca seja commitado
.env
.env.production
.env.staging
*.local
# Carregar ambiente específico com dotenv
import dotenv from 'dotenv'
const envFile = process.env.ENV_FILE || '.env'
dotenv.config({ path: envFile })
# Iniciar com env específico:
ENV_FILE=.env.staging node dist/index.js
# Com docker-compose.override.yml para desenvolvimento
# (sobrescreve configurações de docker-compose.yml)
# docker-compose.override.yml:
# services:
# app:
# volumes:
# - .:/app
# command: npm run dev$ runstack deploy --plan starter
Não quer configurar manualmente?
Não quer configurar manualmente? Implante o VPS em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.