Como colocar uma aplicação Node.js em produção

CONTEÚDO TBF HOST

Como colocar uma aplicação Node.js em produção

No ambiente local, colocar uma aplicação Node.js no ar é um comando. Em produção, é um conjunto de decisões — e a maior parte dos problemas de aplicações recém-publicadas vem de tratar as duas situações como se fossem a mesma coisa.

A diferença central: no seu computador, o processo roda enquanto o terminal está aberto e você está olhando. Em produção, ele precisa sobreviver a fechamento de sessão, reinicialização do servidor, exceções não tratadas e picos de carga — sem que ninguém esteja acompanhando.

Este guia cobre o que muda nessa transição: como o processo deve ser gerenciado, por que a aplicação não deve ficar exposta diretamente à internet, como tratar versões e variáveis, e o que precisa existir antes de considerar o serviço em produção de verdade.

Por que Node.js não roda em hospedagem compartilhada

Vale começar por aqui, porque é a primeira barreira que quase todo mundo encontra.

A hospedagem compartilhada tradicional é construída para um modelo específico: o servidor web recebe a requisição, aciona um interpretador que executa o código, devolve a resposta e encerra o processo. Nada permanece rodando entre uma visita e outra.

Uma aplicação Node.js funciona ao contrário. Ela é o servidor: um processo de longa duração que escuta em uma porta, mantém estado em memória e atende requisições sucessivas sem reiniciar. Esse modelo exige o que ambientes compartilhados não oferecem — processo permanentemente ativo, porta própria e acesso ao sistema.

Por isso, a resposta prática é um servidor com acesso root, onde você controla o que roda e como.

A primeira decisão: qual versão

O Node.js tem um ciclo de lançamentos previsível, com versões de suporte de longo prazo — as LTS — recebendo correções por um período estendido.

A regra para produção é curta: use uma versão LTS ativa. Versões ímpares e recém-lançadas trazem novidades, mas têm janela de suporte curta e não são o lugar de descobrir incompatibilidade de biblioteca em ambiente de produção.

Duas práticas que evitam problema:

  • Fixe a versão no projeto, para que o ambiente de desenvolvimento e o de produção não divirjam silenciosamente.
  • Acompanhe o calendário oficial de lançamentos, que indica quando cada versão entra e sai de suporte. Planejar a atualização com antecedência é mais barato do que migrar às pressas quando o suporte encerra.

Como o calendário avança a cada ano, vale consultá-lo na data da decisão em vez de assumir que a versão instalada continua sendo a recomendada.

O processo precisa de um supervisor

Esta é a diferença mais concreta entre desenvolvimento e produção.

Rodar a aplicação diretamente pelo terminal funciona até a sessão fechar. Em produção, o processo precisa de algo que o mantenha vivo — um gerenciador de processos ou um serviço do sistema operacional.

O que esse supervisor precisa garantir:

  1. Iniciar automaticamente quando o servidor reinicia.
  2. Reiniciar a aplicação se ela encerrar por exceção não tratada.
  3. Registrar a saída em arquivos de log em vez de descartá-la no terminal.
  4. Limitar reinícios em cadeia, para que uma aplicação que falha ao iniciar não entre em laço infinito.
  5. Permitir múltiplas instâncias, quando fizer sentido aproveitar mais de um núcleo de processamento.

Sobre o último ponto: o Node.js executa o código da aplicação em uma única linha de execução. Um servidor com quatro núcleos, rodando uma única instância, usa efetivamente um deles. Executar várias instâncias da aplicação e distribuir a carga entre elas é o modo padrão de aproveitar o hardware — e é uma decisão de arquitetura, porque exige que a aplicação não guarde estado local entre requisições.

Proxy reverso: por que a aplicação não fica exposta

Tecnicamente, é possível fazer o Node.js escutar diretamente na porta pública. Na prática, quase nunca é o que se faz.

O padrão é colocar um servidor web à frente, atuando como proxy reverso, e deixar a aplicação escutando apenas internamente. As razões são práticas:

  • Terminação de TLS. O certificado e a renovação ficam em um só lugar, independentemente de quantas aplicações rodem no servidor.
  • Arquivos estáticos. Servidores web entregam arquivos estáticos de forma mais eficiente do que a aplicação.
  • Múltiplas aplicações. Vários serviços podem dividir o mesmo servidor, roteados por domínio ou por caminho.
  • Controle de tráfego. Limites de requisição, cabeçalhos de segurança e regras de acesso ficam na camada certa.
  • Isolamento. A aplicação deixa de estar diretamente exposta à internet.

Um detalhe que gera confusão frequente: atrás de um proxy, a aplicação passa a ver o endereço do proxy como origem de todas as requisições. Se você usa o IP do cliente para qualquer coisa — registro, limitação de taxa, geolocalização —, é preciso configurar a aplicação para confiar no cabeçalho encaminhado pelo proxy. Do contrário, todos os acessos parecem vir do mesmo lugar.

Configuração e segredos

Chaves de API, credenciais de banco e endereços de serviço não pertencem ao código. A prática consolidada é mantê-los em variáveis de ambiente, definidas no servidor e nunca versionadas.

Três cuidados que evitam incidentes:

Separe os ambientes. Desenvolvimento, homologação e produção precisam de credenciais distintas. Compartilhar a mesma chave entre eles significa que um erro em teste pode afetar dados reais.

Ative o modo de produção. Muitos frameworks alteram comportamento conforme a variável de ambiente: desativam páginas de erro detalhadas, ativam cache interno e reduzem verbosidade. Rodar em modo de desenvolvimento em produção expõe informação e desperdiça desempenho.

Restrinja o acesso ao arquivo de configuração. Ele contém segredos e deve ter permissão restrita ao usuário que executa a aplicação.

Logs e observabilidade

Uma API que falha silenciosamente é pior que uma que cai — porque ninguém percebe.

O mínimo viável para uma aplicação em produção:

  • Log estruturado, em formato consultável, com nível de severidade e identificador de requisição. Texto solto é difícil de investigar sob pressão.
  • Rotação de arquivos. Logs sem rotação enchem o disco, e disco cheio derruba a aplicação e o banco juntos. É uma das causas mais comuns de indisponibilidade não explicada.
  • Endpoint de saúde. Uma rota simples que confirma que a aplicação responde e que suas dependências estão acessíveis. É o que permite monitoramento automático.
  • Alerta ativo. Monitorar disponibilidade e consumo, com aviso antes do teto — não depois da queda.

Vale distinguir dois tipos de falha: a aplicação parou, e a aplicação continua respondendo mas está degradada. A segunda é mais comum e mais difícil de detectar sem instrumentação.

Publicação e retorno

Publicar uma versão nova envolve mais do que copiar arquivos:

  1. Instalar dependências de forma reprodutível, respeitando o arquivo de bloqueio para que produção receba exatamente as mesmas versões testadas.
  2. Executar o build, quando houver etapa de compilação ou transpilação.
  3. Aplicar migrações de banco, se existirem, com atenção à ordem em relação ao código novo.
  4. Recarregar a aplicação de forma que as requisições em andamento sejam concluídas antes do encerramento das instâncias antigas.
  5. Verificar o estado pelo endpoint de saúde antes de considerar a publicação concluída.

E o item que costuma faltar: um caminho de volta. Manter a versão anterior disponível para retorno rápido é o que transforma uma publicação problemática em um incidente de minutos em vez de uma noite inteira.

Dimensionamento: o que realmente pesa

O consumo de uma aplicação Node.js depende menos de tráfego bruto e mais da natureza do trabalho que ela faz.

Aplicações limitadas por entrada e saída — que passam a maior parte do tempo esperando banco de dados, APIs externas ou disco — são o cenário em que o Node.js se destaca. Elas atendem muitas requisições simultâneas com pouco processamento.

Aplicações limitadas por processamento — que fazem cálculo pesado, processam imagens, geram relatórios ou manipulam grandes estruturas em memória — são o oposto. Como o código roda em uma única linha de execução, uma tarefa pesada bloqueia as demais requisições enquanto executa. Nesses casos, a solução costuma ser mover o trabalho para uma fila processada separadamente, e não simplesmente contratar mais memória.

Por isso, dimensionar sem conhecer o perfil da aplicação produz erro nos dois sentidos. O ponto de partida correto é medir: consumo de memória sob carga real, tempo de resposta por rota e comportamento em pico.

Antes de considerar em produção

Uma lista curta de verificação:

  • A aplicação inicia sozinha após reinicialização do servidor?
  • Ela se recupera de uma exceção não tratada?
  • Está atrás de proxy reverso, com HTTPS e renovação automática?
  • Os segredos estão fora do código e separados por ambiente?
  • Os logs têm rotação configurada?
  • Existe endpoint de saúde e alguém é avisado quando ele falha?
  • A publicação tem caminho de retorno testado?
  • O backup inclui o banco e a configuração — e a restauração já foi testada?

Conclusão

Levar uma aplicação Node.js para produção é menos sobre o código e mais sobre o entorno: quem mantém o processo vivo, quem recebe o tráfego antes dele, onde ficam os segredos, o que acontece quando algo falha e como voltar atrás.

As decisões que mais evitam problema são baratas no início e caras depois: versão LTS fixada, supervisor de processo configurado, proxy reverso com TLS, logs com rotação e um caminho de retorno testado. Aplicações que “caíram sem motivo” quase sempre não tinham uma dessas.

Se você está definindo onde publicar, o requisito de partida é um ambiente que execute processos de longa duração com recursos reservados. Conheça o Cloud Server para Node.js da TBF Host e avalie a configuração adequada ao perfil da sua aplicação.

Perguntas frequentes

Posso hospedar uma aplicação Node.js em hospedagem compartilhada?

Em geral não. A hospedagem compartilhada é construída para executar código a cada requisição e encerrar o processo em seguida. Uma aplicação Node.js é um processo de longa duração que escuta em uma porta e mantém estado em memória, o que exige um servidor com acesso ao sistema operacional.

Qual versão do Node.js usar em produção?

Uma versão de suporte de longo prazo em fase ativa de suporte. Versões recém-lançadas têm janela de suporte curta e maior risco de incompatibilidade com bibliotecas. Vale fixar a versão no projeto e acompanhar o calendário oficial de lançamentos para planejar a atualização antes do fim do suporte.

Preciso de um gerenciador de processos para Node.js?

Sim. Rodar a aplicação diretamente pelo terminal funciona apenas enquanto a sessão está aberta. Em produção, é necessário algo que inicie a aplicação automaticamente após reinicialização do servidor, reinicie o processo em caso de falha, registre a saída em log e limite reinícios em cadeia.

Por que usar proxy reverso na frente de uma aplicação Node.js?

Para centralizar a terminação de TLS e a renovação do certificado, entregar arquivos estáticos de forma mais eficiente, permitir que várias aplicações dividam o mesmo servidor, aplicar limites de tráfego e cabeçalhos de segurança na camada correta e evitar que a aplicação fique diretamente exposta à internet.

Uma aplicação Node.js aproveita todos os núcleos do servidor?

Não automaticamente. O código da aplicação é executado em uma única linha de execução, de modo que uma instância usa efetivamente um núcleo. Para aproveitar o restante, executam-se várias instâncias com a carga distribuída entre elas — o que exige que a aplicação não guarde estado local entre requisições.

Onde guardar chaves e credenciais de uma aplicação em produção?

Em variáveis de ambiente definidas no servidor, fora do código e nunca versionadas. Cada ambiente — desenvolvimento, homologação e produção — deve ter credenciais próprias, para que um erro em teste não afete dados reais. O arquivo de configuração deve ter permissão restrita ao usuário que executa a aplicação.

Por que minha aplicação vê o mesmo IP em todas as requisições?

Porque ela está atrás de um proxy reverso e enxerga o endereço do proxy como origem de todo o tráfego. É preciso configurar a aplicação para confiar no cabeçalho encaminhado pelo proxy, o que restaura o IP real do cliente para registro, limitação de taxa e geolocalização.

Quanto de memória uma aplicação Node.js precisa?

Depende do perfil do trabalho que ela realiza. Aplicações que passam a maior parte do tempo esperando banco de dados ou APIs externas atendem muitas requisições simultâneas com pouco consumo. Aplicações que fazem cálculo pesado ou manipulam grandes estruturas em memória se comportam de forma bem diferente, e o caminho costuma ser mover esse trabalho para uma fila separada.

Facebook
X
LinkedIn