Executando verificação de segurança...
1

Seu App Não Acabou Quando Você Terminou o Código

Criar um sistema num fim de semana virou quase trivial.

Você abre o Cursor, pede pra IA montar a base, sobe um backend em .NET, um frontend em React, conecta num Postgres e... pronto. Rodando local. Bonito. Funcional.

E aí vem a frase clássica: "agora é só publicar."

Não. Publicar um site e manter um sistema no ar são coisas completamente diferentes.

Se você quer crescer como dev — principalmente se quer construir SaaS, projetos próprios ou até se destacar em entrevistas técnicas — você precisa dominar deploy com o mesmo nível de profundidade que domina código.

Esse post é o guia que eu queria ter lido quando comecei a publicar sistemas de verdade.


A ilusão do "tá pronto"

Plataformas como Vercel, Railway, Render e similares facilitaram muito a vida. Você conecta o GitHub, clica em deploy e o sistema sobe.

Mas isso funciona bem pra coisas simples: landing pages, blogs, frontend isolado, APIs sem muita dependência.

O problema começa quando seu projeto vira sistema de verdade:

  • Frontend em React
  • Backend em .NET ou Node
  • Banco Postgres com migrations
  • Worker processando filas
  • Cache com Redis
  • Variáveis de ambiente diferentes pra staging e produção
  • Armazenamento externo (S3, Cloudflare R2, etc.)

De repente, "deploy" não é mais um botão. É uma sequência de operações que precisam acontecer na ordem certa.


Anatomia de um desastre (cenário real)

Vamos pegar algo simples: upload de foto de perfil.

Você implementa:

  1. Migration criando coluna avatar_url
  2. Nova rota POST /upload no backend
  3. Componente de upload no frontend

Funciona local. Testes passando. Push na main. E aí...

Frontend sobe primeiro

O frontend começa a chamar POST /upload, mas o backend ainda tá na versão antiga.

Resultado: 404 em produção. Usuário já vendo erro.

Backend sobe, mas a migration não rodou

O backend tenta fazer:

INSERT INTO users (avatar_url)

Mas a coluna ainda não existe.

Resultado: 500. Login quebrado. Cadastro quebrado. Caos.

Migration roda antes do backend novo

Se você fez algo assim:

ALTER TABLE users RENAME COLUMN avatar TO avatar_url;

O backend antigo (que ainda tá rodando) continua tentando acessar avatar.

Resultado: quebrou de novo.

Percebe o padrão? Não foi o código que falhou. Foi a ordem.

Deploy não é sobre código. É sobre coordenação.


A ordem correta das operações

Deploy de sistema é como cozinha de restaurante. Existe sequência. Existe dependência. Se você manda servir o prato antes de cozinhar, deu ruim.

A estrutura típica de um pipeline é:

Testes → Migrations → Backend → Frontend → Workers

E por quê nessa ordem?

Testes primeiro — se falhar aqui, você não publica nada. Simples assim.

Migrations — são perigosas. Mexem em dados reais. Precisam rodar antes do backend depender da nova estrutura.

Backend — agora ele conhece o banco atualizado e consegue funcionar.

Frontend — só deve subir quando as rotas novas já existem no backend.

Workers — dependem de tudo acima estar consistente.

Parece óbvio quando você lê assim. Mas no dia a dia, a maioria dos deploys quebrados acontecem porque alguém ignorou essa ordem.


CI/CD: o funcionário que nunca esquece

Você não quer ficar lembrando dessa ordem manualmente. Você quer automatizar.

Ferramentas como GitHub Actions permitem definir dependências explícitas entre etapas. Olha um exemplo simplificado:

name: Deploy
on:
  push:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm test

  migrate:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - run: npx prisma migrate deploy

  deploy-backend:
    needs: migrate
    runs-on: ubuntu-latest
    steps:
      - run: docker build -t backend .
      - run: docker push backend

  deploy-frontend:
    needs: deploy-backend
    runs-on: ubuntu-latest
    steps:
      - run: npm run build
      - run: vercel --prod

A palavra-chave aqui é needs. Cada etapa só roda se a anterior passar.

Sem improviso. Sem deploy quebrado às 3 da manhã porque você esqueceu de rodar a migration antes.


Migrations: o ponto mais subestimado do deploy

Se você só guardar uma coisa desse post inteiro, guarda essa:

Migration mal feita quebra produção.

Algumas boas práticas que eu aprendi na dor:

Prefira mudanças aditivas. Adicionar coluna é muito mais seguro do que renomear.

Não delete coluna de primeira. Primeiro para de usar no código, deploya, e só depois remove a coluna num deploy futuro.

Evite mudanças destrutivas diretas. Renomear coluna pode exigir uma etapa intermediária.

O caminho seguro pra aquele exemplo do avatar seria:

  1. Criar nova coluna avatar_url
  2. Atualizar o backend pra usar a coluna nova
  3. Migrar os dados antigos
  4. Remover a coluna antiga num deploy futuro

Isso tem um nome: compatibilidade temporária. Parece overhead, mas é o que separa deploy amador de deploy profissional.


Cloud gerenciada vs VPS: a decisão estratégica

Essa é uma dúvida que aparece sempre. Vou simplificar.

Plataformas gerenciadas (Vercel, Railway, Render)

Prós: setup em minutos, SSL automático, escala simplificada, logs prontos.

Contras: custo cresce rápido, menos controle, lock-in.

Ideal pra: MVP, validação, projetos solo. Quando você precisa de velocidade e não quer gastar energia com infra.

VPS (DigitalOcean, Hetzner, AWS EC2)

Prós: custo previsível, controle total, arquitetura customizada.

Contras: você configura tudo, precisa saber Linux, manutenção é sua responsabilidade.

Ideal pra: projeto que já validou, SaaS com custo crescendo, ou quem quer aprender infraestrutura de verdade.

A real é: você provavelmente vai começar com plataforma gerenciada e migrar pra VPS quando o custo ou a necessidade de controle justificar. E tá tudo bem. Faz parte do processo.


Roadmap realista de evolução

Não tenta fazer tudo de uma vez. Vai por fases:

Fase 1 — Validação

Objetivo: velocidade. Front na Vercel, backend na Railway. Pipeline manual. Logs básicos. Aqui o importante é validar se sua ideia tem perna.

Fase 2 — Primeiros usuários

Objetivo: confiabilidade mínima. Adiciona CI básico, backup automático e testes rodando no push. Seu sistema não pode mais cair sem você saber.

Fase 3 — Projeto sério

Objetivo: robustez. Pipeline com migrations automatizadas, Docker, ambientes separados (staging e prod), monitoramento com Sentry e logs estruturados.

Fase 4 — Escala

Objetivo: performance. Load balancer, cache com Redis, CDN, observabilidade real com métricas e tracing. Aqui você já tá jogando no modo avançado.


Monitoramento: a parte que ninguém quer ler (mas que salva)

Deploy não termina quando o sistema sobe. Você precisa saber:

  • Tá respondendo 200?
  • Tá lento?
  • Tá consumindo CPU demais?
  • Alguma rota tá gerando erro silencioso?

Ferramentas que resolvem isso: Sentry pra erros, logs estruturados, health checks e uptime monitoring.

Deploy sem monitoramento é fé. E fé não escala.


Backup e recuperação

Pergunta simples: se seu banco apagar agora, quanto você perde?

Se a resposta for "tudo", você não tem deploy profissional. Você tem um castelo de cartas.

Tenha: backup automático, snapshot periódico e — essa é a parte que todo mundo esquece — teste de restauração. Backup que nunca foi testado é placebo. Você não sabe se funciona até precisar dele.


IA escreve código. Você sustenta o sistema.

Criar sistema ficou fácil. Qualquer pessoa com acesso a uma IA consegue gerar um CRUD funcional em horas.

Mas manter sistema ainda exige entender ordem de deploy, entender banco, entender dependências, entender rollback, entender infraestrutura.

Quando alguém fala "eu sei criar SaaS em um fim de semana", a pergunta que eu faço é: você sabe manter ele vivo por um ano?

Criar é capítulo 1. Deploy é capítulo 2. Operação é capítulo 3. Escala é capítulo 4.

E é nesse ponto que o dev júnior vira dev sério.


Checklist: seu projeto tá pronto pra produção?

  • Testes rodando automaticamente
  • Pipeline com ordem definida
  • Migrations seguras
  • Ambientes separados (staging e prod)
  • Monitoramento ativo
  • Backup automatizado
  • Processo de rollback definido

Se você marcou menos da metade, seu app ainda não terminou.

Carregando publicação patrocinada...