Ambientes de desenvolvimento, staging e produção

Desenvolvimento é onde você escreve o código, staging é uma cópia parecida com produção para a checagem final, e produção atende os usuários reais. Cada um tem config, segredos e dados próprios, rodando o mesmo código.

Atualizado em 8 min de leitura

Objetivos de aprendizado

Depois de ler este artigo, você vai conseguir:

  • Explicar para que serve cada ambiente e quando vale a pena ter staging
  • Separar config, segredos e bancos de dados por ambiente
  • Promover o mesmo código de desenvolvimento para staging e para produção
Nesta página

Todo app começa do mesmo jeito: você roda no notebook, funciona, sobe para o servidor e os usuários reais passam a usar. O problema começa quando o "na minha máquina funciona" encontra um banco de produção, uma chave de API diferente ou um provedor de pagamento que cobra cartões de verdade.

Ambientes separados resolvem isso. Você roda o mesmo código em mais de um lugar, e cada lugar tem configuração e dados próprios. Um erro num deles não alcança os outros.

push em developmerge na main+ aprovação manualDesenvolvimentosua máquinaa1b2c3ddevelopmentchave localdados falsosStagingchecagem finala1b2c3dstagingchave de testeanonimizadosProduçãousuários reaisa1b2c3dproductionchave realdados reais
O mesmo commit passa pelos três ambientes; só a config, os segredos e os dados mudam de um para outro.

O que são desenvolvimento, staging e produção?#

Um ambiente é uma cópia em execução do seu app junto com tudo de que ele depende: config, segredos, banco de dados e armazenamento.

Ambiente Quem usa Dados Para quê
Desenvolvimento Você, na sua máquina Falsos, descartáveis Escrever e depurar código rápido
Staging Você e a equipe, às vezes um cliente Falsos ou anonimizados Checagem final de um build parecido com produção
Produção Usuários reais Reais Servir o app no ar

Algumas equipes adicionam um ambiente de preview por pull request, ou chamam o staging de "QA" ou "homologação". Os nomes não importam. O que importa é que cada um seja isolado.

Por que o staging compensa o trabalho extra?#

O desenvolvimento local esconde problemas que só aparecem num servidor: uma variável de ambiente faltando, outra versão de runtime, uma regra de firewall, um banco muito maior que os seus dados de teste. O Twelve-Factor App chama essas diferenças de problema de paridade entre dev e prod e aponta três lacunas: o tempo entre escrever e publicar o código, quem escreve versus quem faz o deploy, e as ferramentas usadas em cada lugar.

O staging fecha a lacuna das ferramentas. Ele roda num servidor, com o mesmo runtime e o mesmo tipo de banco da produção, então uma falha aparece antes de chegar aos usuários. Também é o lugar certo para testar o que nunca deve ser testado em dados reais: migrações de banco, webhooks de pagamento no modo de teste do provedor e importações em massa.

Nem sempre você precisa dele. Um bot de hobby, de uma pessoa só e sem usuários pagantes, pode pular o staging, desde que você consiga voltar atrás rápido. Adicione quando um deploy ruim custar dinheiro ou confiança.

O que precisa ser diferente entre os ambientes?#

Três coisas mudam de um ambiente para outro, e nada mais deveria mudar.

1. Configuração. O Twelve-Factor App guarda a config no ambiente, não no código. Tudo o que varia entre deploys é config: URLs de banco, chaves de API, a URL pública, o nível de log. O código lê tudo isso de variáveis de ambiente, como explicado em o que são variáveis de ambiente.

2. Segredos. O staging deve usar tokens e chaves diferentes dos de produção. Se uma chave de staging vazar, ou alguém da equipe colar a chave num chat, a produção continua segura. Em provedores de pagamento e plataformas de bot, use o modo de teste ou um bot de teste separado, nunca as credenciais reais.

3. Dados. Nunca aponte o staging para o banco de produção. Um script de teste com bug editaria linhas reais. Crie um banco separado, com o mesmo motor e a mesma versão da produção. Preencha com dados falsos, ou com uma cópia da produção da qual nomes, e-mails e tokens foram removidos ou embaralhados.

Todo o resto, da versão do runtime à lista de dependências, deve ser igual. O código é o mesmo commit em todos os ambientes.

Como montar os ambientes, passo a passo?#

1. Escolha uma variável que dê nome ao ambiente. Por exemplo, APP_ENV com os valores development, staging e production. Use-a em logs e em poucos ajustes, não para grandes mudanças de comportamento. Quanto mais o código se ramifica pelo nome do ambiente, menos o staging prova.

2. Carregue a config num lugar só. Este módulo Node.js lê as variáveis uma vez, falha logo quando falta alguma e deixa o resto do código livre de process.env:

js
// config.js
const required = (name) => {
  const value = process.env[name];
  if (!value) throw new Error(`Missing environment variable: ${name}`);
  return value;
};

export const config = {
  env: process.env.APP_ENV ?? "development",
  databaseUrl: required("DATABASE_URL"),
  apiKey: required("API_KEY"),
  logLevel: process.env.LOG_LEVEL ?? "info",
};

Na sua máquina, coloque os valores num arquivo .env que não vai para o commit (veja o arquivo .env). No servidor, defina nas configurações de ambiente da plataforma. Nas versões recentes do Node.js, o próprio runtime carrega o arquivo, sem biblioteca: node --env-file=.env config.js.

3. Crie um app e um banco separados por ambiente. O staging ganha app próprio, banco próprio e domínio ou subdomínio próprio. Não reaproveite o app de produção com uma flag diferente.

4. Ligue branches a ambientes. Um fluxo comum: branches de feature são testadas localmente, um push em develop ou staging faz deploy no staging, e um merge na main faz deploy em produção. Mantenha as branches curtas para o staging não se afastar da main.

5. Promova o mesmo código. O que você testou no staging deve ser exatamente o commit que vai para produção. Se você recompila a partir de outras fontes, ou faz merge de mudanças extras depois do teste, o resultado do staging deixa de provar qualquer coisa.

Como automatizar a promoção com GitHub Actions?#

O GitHub Actions tem um recurso feito para isso: os environments. Um environment é um destino com nome, como staging ou production. Cada um guarda secrets e variáveis próprios, e um job que declara environment: production lê os valores daquele environment. Para produção, você também pode exigir que um revisor aprove a execução, adicionar um tempo de espera ou restringir quais branches podem fazer deploy.

Os secrets de um environment só chegam aos jobs que o referenciam. Há também limitações por plano: em repositórios privados, os environments e regras como revisores obrigatórios e tempo de espera dependem do plano do GitHub, então confira a documentação de environments para o seu caso.

Este workflow faz deploy no staging a cada push em develop e em produção a cada push na main, usando o mesmo script de deploy com valores diferentes:

yaml
name: Deploy

on:
  push:
    branches: [develop, main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-node@v7
        with:
          node-version: lts/*
      - run: npm ci
      - run: npm test

  deploy:
    needs: test
    runs-on: ubuntu-latest
    environment:
      name: ${{ github.ref_name == 'main' && 'production' || 'staging' }}
    steps:
      - uses: actions/checkout@v7
      - name: Deploy
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
          TARGET_APP: ${{ vars.TARGET_APP }}
        run: ./scripts/deploy.sh

Crie dois environments em Settings > Environments e defina DEPLOY_TOKEN e TARGET_APP em cada um, com valores diferentes. O arquivo do workflow continua idêntico. Onde o seu plano permitir, ative revisores obrigatórios para production, para uma pessoa confirmar a release. Para o básico de workflows, veja deploy automático com GitHub Actions.

Como lidar com mudanças de banco entre ambientes?#

Mudança de schema é a parte mais arriscada da promoção. Escreva as mudanças como arquivos de migração no repositório, rode primeiro no staging e só depois em produção. Se uma migração falha ou demora demais no staging, você descobriu sem pagar por isso. Migrações de banco no deploy cobre a ordem e os padrões seguros.

Os dados do staging raramente são tão grandes quanto os de produção. Uma migração que leva um segundo em algumas centenas de linhas pode travar uma tabela por minutos em milhões. Se esse risco importa, teste com uma cópia anonimizada dos dados de produção.

Quais são os erros mais comuns?#

  • Staging apontando para recursos de produção. Basta um .env copiado para o staging escrever no banco real ou mandar e-mails de verdade. Dê nomes claros às variáveis e revise tudo ao criar um ambiente.
  • Segredos compartilhados entre ambientes. Uma chave de staging vazada não pode abrir a produção.
  • Staging desatualizado. Se ele roda uma branch velha, outra versão de runtime ou outra versão do motor de banco, passar nele prova pouco. Atualize a cada merge.
  • Testar com código diferente do de produção. Não coloque atalhos como if (staging) que pulam a autenticação ou simulam serviços que você usa em produção.
  • Notificações reais saindo do staging. Bots de staging que entram em servidores reais, ou apps que mandam e-mail para clientes reais, causam confusão. Use contas de teste, um token de bot de teste e uma sandbox de e-mail.
  • Pular a checagem depois do deploy. Pipeline verde só significa que o comando terminou. Abra o app e leia os logs depois de cada release.

Como fazer isso na Square Cloud#

Na Square Cloud, cada ambiente é uma aplicação própria com variáveis de ambiente próprias, então staging e produção nunca dividem config por acidente. Crie uma aplicação para produção e outra para staging. As variáveis ficam por aplicação no painel, na API, na CLI ou na extensão do VS Code; o painel importa um arquivo .env, e a mudança vale no próximo restart, sem rebuild. A variável SQUARECLOUD_APP_ID entrega o ID da aplicação em runtime, o que ajuda nos logs.

Para os dados, a hospedagem de bancos começa no plano Standard; a partir dele, crie um banco separado para o staging e dê a cada app a própria string de conexão. Aplicações web ganham um subdomínio *.squareweb.app em todo plano, o que basta para uma URL de staging; domínio personalizado para produção começa no plano Standard. A RAM do plano é um pool compartilhado por todas as suas aplicações, com mínimo de 256 MB por aplicação de fundo e 512 MB por aplicação web, então a cópia de staging consome do mesmo pool que a produção.

Para automatizar a promoção, use a GitHub Action oficial com o padrão de environments acima. Salve SQUARECLOUD_API_KEY como secret e o ID da aplicação como a variável SQUARECLOUD_APP_ID em cada environment do GitHub:

yaml
      - uses: actions/checkout@v7
      - uses: squarecloudofc/github-action@v2
        with:
          token: ${{ secrets.SQUARECLOUD_API_KEY }}
          command: commit ${{ vars.SQUARECLOUD_APP_ID }} --restart

O environment de staging guarda o ID da aplicação de staging, e o de produção guarda o da produção. Antes de uma release arriscada, tire um snapshot manual da aplicação de produção pelo painel; snapshots manuais existem em todo plano, e um snapshot restaura na mesma aplicação ou, em um clique, numa aplicação nova. O arquivo de configuração squarecloud.app é opcional: o painel gera no deploy, e escrever na raiz do projeto é a alternativa. A página da GitHub Action mostra o workflow completo e as entradas da action.

Deploy

Envie pelo GitHub, pela CLI ou em ZIP e publique em segundos

Saiba mais

Perguntas frequentes

Preciso de um ambiente de staging num projeto pequeno?

Nem sempre. Se você é o único desenvolvedor e um deploy ruim custa pouco, um bom setup local e um rollback rápido podem bastar. Adicione staging quando errar ficar caro: usuários pagantes, banco compartilhado, pagamentos ou uma equipe.

O staging pode usar o banco de dados de produção?

Não. Um teste, uma migração ruim ou um script com bug alterariam dados de usuários reais. Dê ao staging um banco próprio, com dados falsos ou anonimizados.

O staging deve rodar o mesmo código da produção?

Sim. A razão de existir do staging é testar exatamente o código que vai para produção. Só a configuração muda, como a URL do banco, as chaves de API e o nome do ambiente.

Quantos ambientes eu preciso?

Dois é o mínimo comum: a sua máquina para desenvolvimento e a produção. Um terceiro, o staging, fica entre os dois. Equipes grandes adicionam mais, como um ambiente de preview por pull request.

Próximo artigoO que é Docker ComposeDocker Compose descreve uma aplicação com vários containers em um arquivo YAML e sobe tudo com um comando. Veja como funciona, um exemplo e os limites.