Para Que Funcione - Los 6 pasos para que tu empresa sea sostenible y funcione sin ti ...
Los 6 pasos para que tu empresa sea sostenible y funcione sin ti ...

O problema que todo mundo enfrenta na hora de colocar algo pra rodar

Você instala as dependências, roda o comando e nada. Ou pior: funciona na sua máquina mas quebra no servidor de produção. Isso acontece porque existe uma diferença enorme entre o que você pensa que está configurado e o que realmente está rodando. Eu passei anos resolvendo isso em ambientes de desenvolvimento e, acredite, a maioria dos erros vem de coisas óbvias que ninguém verifica. O que eu vou descrever aqui não é teoria de livro. É o que eu fiz na prática quando um projeto inteiro parou de funcionar numa sexta à tarde, duas horas antes de ir ao ar. Ninguém queria ouvir desculpas, queria solução.

Configurando para que funcione

A primeira coisa que você precisa entender é que a ordem importa. Não adianta ter todas as peças certas se você as monta na sequência errada. Eu já vi gente configurar o ambiente de produção antes de garantir que o ambiente local estava isolado. O resultado foi uma base de dados que recebeu dados de teste durante o deploy, e levar três dias inteiros para limpar tudo. Veja a sequência que funciona. Primeiro, verifique a versão do runtime. Simplesmente rodar --version não basta. Você precisa checar se a versão que o gerenciador de pacotes reconhece é a mesma que está no PATH do sistema. No meu caso, tive um projeto onde o node --version mostrava 18.16.0, mas o processo que o PM2 ia iniciar estava usando 16.13.1. O código usava optional chaining, que só existe a partir do 14, então teoricamente funcionaria em ambos. Mas uma biblioteca interna dependia de uma feature nativa que mudou entre essas versões. O erro só apareceu em produção, porque o ambiente de staging rodava com 18 também.

A solução foi criar um arquivo .nvmrc na raiz do projeto com a versão exata e travar o PATH no script de start. Assim, não importa em qual servidor você rodar, o runtime será sempre o mesmo.

Dependências: onde a coisa costuma quebrar

Lock files existem por um motivo. Ignorar isso é pedir para dar pau. O yarn.lock ou package-lock.json não é só um arquivo decorativo que ninguém lê. Ele garante que a versão exata que você testou é a versão que vai rodar. Sem ele, você está confiando na sorte. Um caso específico que eu enfrentei: um projeto Python com requirements.txt que dizia pandas==2.0.3. Na minha máquina, rodava limpo. Na CI, quebrava porque uma dependência transitiva do pandas puxava uma versão diferente do numpy, e essa nova versão do numpy tinha sido compilada com um flag de otimização que não existia no processador do servidor. O erro era silencioso - o import funcionava, mas cálculos simples davam resultado errado. Levou duas semanas rastreando.

A correção foi usar pip-compile para gerar um requirements.txt fechado, com cada dependência transitiva versionada explicitamente. O tempo de geração do arquivo fechado é maior, mas resolve o problema de forma definitiva.

👉 Clique no botão abaixo para saber mais sobre o assunto!

Variáveis de ambiente e secrets

Nunca, em hipótese alguma, coloque credenciais hardcoded no código. Eu sei que é tentador quando você está apressado. Eu já fiz isso. Já vi isso. E o resultado é sempre o mesmo: alguém vai puxar o repositório, usar as credenciais em produção, e aí você descobre que o usuário tinha permissão de escrita em uma tabela que não deveria ter. O padrão que eu recomendo é usar um arquivo .env local que não vai para o versionamento, e carregar as variáveis via um loader específico do framework. Se o framework não tem loader nativo, use dotenv. É trivial de configurar e leva menos de dois minutos.

Outro detalhe importante: variáveis de ambiente no servidor precisam ser verificadas antes do deploy. Eu criava um script de health check que rodava antes de liberar o tráfego, apenas confirmando que todas as variáveis obrigatórias estavam presentes e com formato válido. Se alguma faltasse, o deploy era abortado automaticamente. Isso me salvou de pelo menos cinco incidentes em dois anos.

Testes de integração antes de ir pra produção

Muita gente pula essa etapa. Testa só em unitário e acha que está pronto. Unidade isolada funciona porque você controla o ambiente. Integração é diferente. Você precisa confirmar que os componentes conversam entre si da forma esperada. No projeto que eu mencionei no início, o teste unitário passava em 100%. O teste de integração falhava porque um serviço de cache não estava sendo reinicializado entre os testes, e os dados antigos retornavam nas requisições subsequentes. A correção foi adicionar um teardown explícito no setup dos testes de integração, limpando o cache e reconectando o banco antes de cada suite.

Rodar os testes de integração leva cerca de oito minutos no meu setup. Pular essa etapa economiza minutos agora e gera horas de debugging depois. A conta é simples.

O que acontece quando nada disso funciona

Às vezes você faz tudo certo e ainda assim não roda. Nesse caso, o problema provavelmente está fora do seu controle direto. Pode ser uma limitação do provedor de hospedagem, uma política de rede que bloqueia portas específicas, ou uma dependência externa que mudou sem aviso. Nesses cenários, o mais produtivo é isolar o problema com logs detalhados em vez de continuar tentando ajustes cegos. Ativar logging verbose durante o deploy custa pouco e geralmente revela exatamente onde a corrente quebra. Eu costumo usar logstash ou até algo mais simples como redirecionar stderr para um arquivo temporário e inspecionar linha por linha. Leva cerca de quinze minutos a mais no processo, mas elimina adivinhação.

Se o problema persistir mesmo com logs, considere que talvez a stack escolhida não seja a ideal para o caso. Às vezes mudar de framework ou de ORM resolve em uma tarde o que levaria semanasando a solução atual. Eu já passei por isso com um projeto que usava uma ORM muito pesada para uma consulta simples. Trocar por queries brutas reduziu o tempo de resposta de quatro segundos para cento e vinte milissegundos.