DevPath · Aprenda a programar ESPTEN

Produção e implantação

Configuração: 12-factor e ambientes

O problema da configuração

Um mesmo servidor é executado em vários ambientes: seu notebook (development), um servidor de testes (staging) e produção (production). Cada um precisa de valores diferentes: a porta, a URL do banco de dados, as chaves de APIs externas... Se você hardcoda esses valores no código, mistura o que muda (a config) com o que não muda (o programa), e acaba com um if (ambiente === "prod") espalhado por toda parte.

A metodologia 12-factor

The Twelve-Factor App é um conjunto de boas práticas para construir serviços. Seu fator III (Config) diz:

Guarde a configuração no ambiente, não no código.

Em concreto:

// No Node, as variáveis de ambiente chegam em process.env (sempre strings).
const PORT = process.env.PORT;          // "3000"
const NODE_ENV = process.env.NODE_ENV;  // "production"

Centralizar e definir valores padrão

Em vez de ler process.env por todo o código, centralize a leitura em um único módulo de config que valida e aplica valores padrão. Assim o resto da aplicação recebe um objeto limpo e tipado:

function carregarConfig(env) {
  return {
    port: Number(env.PORT) || 3000,
    ambiente: env.NODE_ENV || "development",
  };
}

const config = carregarConfig(process.env);

Nestes exercícios injetamos o ambiente como um objeto env (em vez de ler process.env diretamente). Isso torna a config testável: você pode testar a mesma função com {}, com { PORT: "8080" }, etc.

Separar config por ambiente

O valor de NODE_ENV decide o comportamento: em development você quer logs detalhados e mensagens de erro completas; em production, logs compactos e erros genéricos (para não vazar detalhes internos). O código é o mesmo; só mudam os valores que ele recebe.

Gerenciamento de segredos

As senhas, tokens e chaves são config especialmente sensível:

Exemplos

Config centralizada com defaults e validação de segredos

function carregarConfig(env) {
  if (env.NODE_ENV === "production" && !env.DATABASE_URL) {
    throw new Error("Falta DATABASE_URL em produção");
  }
  return {
    port: Number(env.PORT) || 3000,
    ambiente: env.NODE_ENV || "development",
    dbUrl: env.DATABASE_URL || "memoria://local",
  };
}

console.log(carregarConfig({ PORT: "8080" }));
console.log(carregarConfig({}));
Coloque isto em prática

O DevPath é um curso prático: aqui você lê a teoria; no app você a coloca em prática com exercícios que rodam de verdade, offline.

Comece grátis no app →
Logging e observabilidade →