Meta descrição: Guia prático de deploy Node.js na VPS com Nginx, PM2 e WebSocket: proxy reverso, SSL e PM2 para uptime máximo.

Fazer deploy Node.js na VPS com Nginx, PM2 e WebSocket é um daqueles passos que parecem complexos no começo, mas viram rotina quando você entende o “porquê” de cada peça. A ideia deste guia é te levar do zero a um ambiente bem próximo do que se usa em produção: sua aplicação Node rodando de forma estável, com reinício automático, atualização sem derrubar conexões e um Nginx na frente cuidando do tráfego HTTP/HTTPS (incluindo upgrade de conexão para WebSocket).
Por que esse combo é tão comum?
- VPS: você tem controle total do servidor (porta, firewall, logs, domínio), sem as limitações típicas de hospedagens compartilhadas.
- PM2: gerencia seu processo Node (restart em caso de crash, logs, modo cluster, startup no boot), e permite o famoso reload zero-downtime.
- Nginx: atua como reverse proxy, terminando SSL, servindo assets estáticos com eficiência e encaminhando requisições para o Node — inclusive tráfego de WebSocket Node.js atrás do Nginx.
Ao final, você vai ter:
- Aplicação rodando em uma porta interna (ex.: 3000)
- Nginx respondendo em 80/443 (HTTP/HTTPS)
- WebSocket funcionando (Upgrade/Connection configurados)
- PM2 garantindo resiliência e deploy mais suave
O guia é voltado para iniciantes, então vou explicar também os detalhes que costumam causar erro: permissões, firewall, arquivo de configuração do Nginx, cabeçalhos de WebSocket e como validar se “está mesmo em produção” (logs, status, health-check).
Pré-requisitos e panorama do ambiente
Antes de configurar qualquer coisa, vale alinhar o “mapa” do que vai acontecer no servidor. Isso evita o cenário clássico: Node ouvindo numa porta, Nginx em outra, DNS apontando errado e você sem saber onde está o gargalo.
O que você precisa ter em mãos
Para seguir este tutorial com tranquilidade, o ideal é:
- Uma VPS Linux (Ubuntu 22.04/24.04 costuma ser o caminho mais simples)
- Acesso via SSH (usuário com sudo)
- Um domínio (opcional, mas recomendado para SSL e para uso real)
- Uma aplicação Node.js (Express/Nest/Fastify/Next custom server, etc.)
O panorama do ambiente (arquitetura mental)
Pense assim: o seu Node.js não precisa “aparecer” diretamente para a internet. Ele pode ficar “escondido” em uma porta local e quem lida com o tráfego público é o Nginx.
- Internet → Nginx (80/443): recebe as requisições, aplica regras e encaminha.
- Nginx → Node.js (localhost:3000): repassa HTTP e também WebSocket (quando configurado).
- PM2: mantém o processo Node vivo, reinicia se cair e ajuda nos reloads.
Isso traz duas vantagens enormes:
1) Segurança: você não precisa abrir a porta do Node para o mundo, só 80/443.
2) Operação: você consegue trocar a aplicação (reload) sem derrubar tudo.
Preparos básicos na VPS (boas escolhas que evitam dor de cabeça)
- Atualize o sistema:
sudo apt update && sudo apt upgrade -y
Crie um usuário de deploy (opcional, mas recomendado) e evite trabalhar como root o tempo todo.
Firewall: se estiver usando UFW, libere apenas o necessário:
- SSH (22), HTTP (80) e HTTPS (443)
- Pasta do projeto: defina um padrão, por exemplo:
/var/www/minha-appou/home/deploy/apps/minha-app
Onde iniciantes costumam errar
- Tentar rodar o Node na porta 80/443 (não precisa; deixe isso para o Nginx)
- Esquecer que WebSocket exige cabeçalhos de upgrade no proxy
- Não configurar o processo para subir no boot (a VPS reinicia e “some” o app)
Com esse panorama claro, a próxima etapa é instalar Node.js e dependências do jeito certo para produção, evitando versões antigas do repositório padrão.
🤖 Um próximo passo natural: automatizar deploys e rotinas com n8n + Agentes de IA
Se você chegou até aqui, provavelmente já percebeu que o deploy não é só “colocar no ar”: tem renovação de SSL, checagem de health, alertas quando o processo cai, rotinas de backup, e por aí vai. Uma forma bem prática de evoluir isso (sem virar refém de mil scripts) é usar automações.
Eu gostei bastante da Formação Agentes de IA (n8n) da Hora de Codar justamente por ser direta para iniciantes e colocar você para construir projetos reais: são 11+ cursos, 221+ aulas, 20h+ de conteúdo e 21+ projetos, além de uma comunidade grande (8100+ alunos). Tem uma parte bem útil sobre configuração profissional em VPS, domínio, SSL e segurança, que conversa com o que você fez aqui.
Se quiser dar uma olhada com calma, o link é este (vale salvar para depois):
https://app.horadecodar.com.br/lp/formacao-agentes-de-ia-n8n?utm_source=blog
Instalação e configuração do Node.js e dependências
Aqui a meta é ter uma instalação de Node.js previsível e fácil de manter. Em VPS, muita gente instala “o Node do apt” e descobre depois que é uma versão antiga — o que vira dor de cabeça com bibliotecas modernas.
Instale o Node.js do jeito recomendado (com NVM ou NodeSource)
Você tem duas rotas comuns:
Opção A) NVM (mais flexível)
O NVM facilita trocar versões, mas exige um pouco mais de cuidado com serviços no boot. Para iniciantes, funciona bem se você mantiver a versão fixa e documentada.
- Instale o NVM
- Instale uma versão LTS (ex.: Node 20 LTS)
- Fixe como padrão
Opção B) NodeSource (mais “server-friendly”)
Geralmente é a opção mais tranquila em produção, pois instala Node como pacote do sistema.
Instale dependências úteis
Mesmo que sua aplicação seja “só Node”, algumas libs e builds podem precisar de ferramentas:
build-essential(compilação)git(para clonar/puxar)curl(para scripts)
Além disso, vale garantir um gerenciador de pacotes:
npmjá vem com Nodepnpmouyarnsão opcionais (use o que seu projeto usa)
Preparando o projeto para produção
Dentro da pasta do projeto:
1) Instale dependências:
npm install
2) Configure variáveis de ambiente:
- Em produção, prefira variáveis no servidor (ou via arquivo
.envcom permissões corretas) - Nunca comite
.envno Git
3) Ajuste scripts importantes no package.json:
- Um
startclaro (ex.:node dist/server.jsounode server.js) - Um build se necessário (TS/Next/Nest)
Porta e bind corretos
Para funcionar com reverse proxy, seu Node deve ouvir em uma porta interna, tipicamente 3000:
PORT=3000- Bind recomendado:
0.0.0.0(ou127.0.0.1se você tiver certeza de que só o Nginx acessa localmente)
Muita gente usa 127.0.0.1 por segurança (não expõe fora), e isso combina perfeitamente com Nginx na mesma máquina.
Teste rápido antes de envolver PM2 e Nginx
Ainda sem PM2, valide se a app responde:
node server.js(ou seu comando)curl http://127.0.0.1:3000/health(se você tiver endpoint de health)
Se isso estiver OK, você já eliminou metade dos problemas possíveis. A próxima etapa é colocar o PM2 para gerenciar o processo e habilitar PM2 startup e reload zero-downtime.
Vídeo recomendado: instalação na VPS (para pegar o “jeito” do deploy)
Mesmo este guia sendo focado em Node.js, vale muito ver um exemplo de instalação em VPS “do mundo real”, porque a lógica de acesso, DNS, SSL e proxy é a mesma. Este vídeo mostra um passo a passo direto de instalação em VPS e ajuda a fixar o fluxo de configuração.
Assista aqui e aproveite para seguir o processo na sua VPS enquanto configura o seu projeto: https://www.youtube.com/embed/VCKzXFk_XjM?si=eOBTMrjZNPj3q07Z
Gerenciando a aplicação com PM2: startup e zero-downtime reload
O PM2 entra como o “operador” da sua aplicação. Ele mantém o Node rodando, registra logs, reinicia se travar e facilita muito a vida quando você precisa atualizar código sem derrubar o serviço.
Instalando o PM2
Instale globalmente:
npm i -g pm2
Depois, dentro do diretório do projeto, inicie a aplicação com um nome claro:
pm2 start npm --name "minha-app" -- start
Isso é útil porque padroniza o comando de start no package.json.
Entendendo o “zero-downtime reload”
O famoso “reload” sem downtime costuma confundir iniciantes. Ele funciona melhor quando você usa modo cluster, porque o PM2 sobe novas instâncias antes de derrubar as antigas.
Em termos simples:
- com 1 processo: reiniciar = uma pequena queda
- com cluster (2+ processos): PM2 troca processos em “rodízio”
Exemplo mental: se a VPS tiver 2 vCPUs, você pode usar instances: 2.
Uma forma prática é criar um ecosystem.config.js:
- define script, instâncias, variáveis, e modo
- permite padronizar ambientes (dev/prod)
Depois:
pm2 start ecosystem.config.jspm2 reload minha-app(tenta fazer reload suave)
Configurando o PM2 para subir no boot (PM2 startup)
Esse é um passo que muita gente pula e só percebe quando reinicia a VPS e o site cai.
A sequência típica é:
1) Gere o comando de startup:
pm2 startup
2) Execute o comando que o PM2 imprimir (ele te dá uma linha com sudo)
3) Salve a lista de processos:
pm2 save
Assim, depois de reboot, o PM2 recria seus processos automaticamente.
Logs e status (o painel de saúde do seu deploy)
Para ver o que está acontecendo:
pm2 status(mostra processos)pm2 logs minha-app(logs em tempo real)
Quando WebSocket está envolvido, logs são ainda mais importantes, porque erros de upgrade/timeout costumam aparecer como 400/502 no proxy.
Dica importante: reinício gracioso
Se a sua aplicação mantém conexões abertas (WebSocket), considere implementar shutdown gracioso no Node (capturar SIGINT/SIGTERM e fechar server). Isso reduz quedas e evita conexões “penduradas”.
Com o Node controlado pelo PM2, o próximo passo é publicar de verdade: configurar Nginx reverse proxy para HTTP e também para WebSocket Node.js atrás do Nginx.
Configurando o Nginx como reverse proxy para Node.js e WebSocket
Agora vem a parte que faz a aplicação “virar site”: o Nginx vai receber as requisições na porta 80/443 e encaminhar para o Node na porta interna. E, para WebSocket, ele precisa suportar o upgrade da conexão.
Instalando o Nginx
No Ubuntu:
sudo apt install nginx -y
Depois, verifique se está ativo:
systemctl status nginx
Conceito-chave: reverse proxy
Quando você configurar Nginx reverse proxy para Node.js, você cria um bloco server apontando o domínio (ou IP) e usando proxy_pass para http://127.0.0.1:3000.
O fluxo fica:
- usuário acessa
https://seu-dominio.com - Nginx recebe
- Nginx encaminha para Node
- resposta volta pelo Nginx
Configuração base (HTTP) + suporte a WebSocket
Crie um arquivo em /etc/nginx/sites-available/minha-app e ative via symlink em sites-enabled.
O ponto crítico para WebSocket é:
proxy_http_version 1.1proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";
Além disso, mantenha cabeçalhos comuns:
Host,X-Forwarded-For,X-Forwarded-Proto
E ajuste timeout para conexões longas:
proxy_read_timeout 60s(ou maior, dependendo do seu caso)
Separando rotas (quando fizer sentido)
Alguns projetos usam WebSocket em um path específico (ex.: /socket), outros usam na raiz. Você pode configurar um location específico para WebSocket e outro para HTTP normal.
Exemplo conceitual:
location /→ proxy normallocation /socket.io/→ proxy com upgrade + timeout maior
Isso ajuda a não “afrouxar” timeouts para o site inteiro.
Testando e recarregando o Nginx
Sempre valide antes de recarregar:
sudo nginx -t
Se estiver OK:
sudo systemctl reload nginx
“Reload” é melhor que “restart” na maioria dos casos, porque evita derrubar conexões ativas do próprio Nginx.
Erros clássicos de WebSocket atrás do Nginx
- 502 Bad Gateway: Node não está rodando, porta errada, ou firewall local bloqueando
- 400/426 em WebSocket: faltou cabeçalho Upgrade/Connection, ou está usando HTTP/2 sem o ajuste adequado
- Conecta e cai:
proxy_read_timeoutbaixo demais
Quando essa camada fica redonda, o deploy já está “funcionando”. O que separa um deploy ok de um deploy profissional são as práticas de SSL, segurança, monitoramento e troubleshooting — que é exatamente o próximo tópico.
💻 VPS para Node.js (e n8n) que costuma facilitar a vida: Hostinger
Se você ainda está escolhendo onde hospedar, uma VPS estável faz diferença real para manter Node + PM2 + Nginx sem surpresas. Uma opção que tem funcionado bem para esse tipo de stack é a VPS da Hostinger, principalmente por ser fácil de gerenciar e permitir escalar recursos conforme o projeto cresce.
O link de indicação é:
https://www.hostinger.com.br/horadecodar
E se for contratar, dá para usar o cupom HORADECODAR para desconto.
O que eu acho legal para quem está começando (e também para projetos que crescem): planos com NVMe, boa quantidade de banda e uma base com 99,9% de uptime, além de suporte 24/7. E, se você também mexe com automação, eles citam que já dá para subir n8n com bem menos fricção.
No fim, o mais importante é: escolher uma VPS que você consiga manter, monitorar e atualizar sem sofrer — porque isso impacta diretamente o uptime do seu deploy.
Boas práticas, SSL, monitoramento e troubleshooting
Depois que tudo está no ar, o trabalho vira “manter no ar”. Essa é a parte que mais salva tempo no futuro: ativar SSL corretamente, observar logs, ter um plano de rollback e saber onde procurar quando algo quebra.
SSL (HTTPS) com Let’s Encrypt
O caminho mais comum é usar Certbot com Nginx.
Passos gerais:
- Instalar
certbote o plugin do nginx - Rodar
certbot --nginxpara o domínio - Verificar renovação automática (timer/cron)
Por que isso importa especialmente para WebSocket?
- Em muitos cenários, o navegador exige WSS (WebSocket seguro) quando a página está em HTTPS.
- Misturar HTTPS com WS (inseguro) costuma ser bloqueado.
Cabeçalhos e “real IP”
Como o Nginx fica na frente, sua aplicação Node precisa confiar nos headers X-Forwarded-* (principalmente para gerar URLs, detectar HTTPS, IP do cliente e rate limiting). Em Express, por exemplo, é comum usar:
app.set('trust proxy', 1)
Monitoramento simples que já resolve 80% dos casos
Você não precisa começar com uma stack gigante. Para iniciantes, faça o básico muito bem:
pm2 statuspara ver se está onlinepm2 logspara erros de runtimejournalctl -u nginx(ou logs em/var/log/nginx/) para erros do proxy
E tenha um endpoint /health respondendo rápido. Isso ajuda a diferenciar:
- “app caiu” vs “proxy quebrou” vs “DNS/SSL”
Performance e estabilidade
- Evite servir arquivos estáticos pesados pelo Node; prefira Nginx quando possível.
- Ative compressão (gzip/brotli) se fizer sentido.
- Se usar PM2 em cluster, valide consumo de RAM e CPU.
Troubleshooting rápido (passo a passo mental)
Quando algo der errado, tente sempre isolar a camada:
1) O Node responde localmente?
curl http://127.0.0.1:3000
2) O PM2 está rodando?
pm2 status/pm2 logs
3) O Nginx está ok?
sudo nginx -t- checar
/var/log/nginx/error.log
4) O domínio aponta para o IP certo?
- checar DNS
5) WebSocket especificamente:
- confirmar headers de upgrade
- aumentar
proxy_read_timeout - validar se o cliente está usando
wss://em produção
Segurança básica que não dá para ignorar
- Atualize pacotes regularmente
- Use chave SSH (evite senha)
- Se possível, desabilite login root via SSH
- Mantenha portas mínimas abertas (80/443/22)
Com esses cuidados, seu deploy Node.js na VPS com Nginx, PM2 e WebSocket fica muito mais resistente. E o melhor: você passa a ter um processo repetível para qualquer projeto novo.
Como configurar o Nginx como proxy reverso para uma aplicação Node.js na VPS?
Após instalar o Nginx, você deve editar o arquivo de configuração para criar um novo server block (virtual host) que faça o redirecionamento das requisições para o endereço local da sua aplicação Node.js (geralmente http://localhost:3000). O proxy_pass deve apontar para sua porta Node.js e também é recomendado configurar os cabeçalhos corretos para suportar WebSockets e HTTPS, se necessário.
Por que usar o PM2 para gerenciar aplicações Node.js na VPS?
O PM2 é um gerenciador de processos para Node.js que permite manter sua aplicação sempre online, facilita o gerenciamento de múltiplas instâncias, faz autorrecuperação em caso de falhas e ainda permite realizar deploys sem downtime. Ele também facilita a configuração de restart automático do app em caso de quedas ou reinicializações do sistema.
Como garantir suporte a WebSocket na configuração do Nginx para Node.js?
Para garantir o suporte ao WebSocket, é preciso adicionar regras específicas no bloco de configuração do Nginx. Certifique-se de adicionar as diretivas ‘proxysetheader Upgrade $httpupgrade;’ e ‘proxysetheader Connection “upgrade”;’ ao bloco de location que faz o proxypass para o Node.js. Isso permitirá a comunicação bidirecional necessária para WebSockets.
Conclusão
Fazer deploy Node.js na VPS com Nginx, PM2 e WebSocket é basicamente montar um pipeline simples e robusto: o Node roda em uma porta interna, o PM2 garante que o processo fique saudável (com PM2 startup e reload zero-downtime quando você usa cluster), e o Nginx publica sua aplicação como reverse proxy, cuidando de SSL e do tráfego — inclusive quando você precisa de WebSocket Node.js atrás do Nginx.
Se você seguir a ordem certa (Node funcionando localmente → PM2 gerenciando → Nginx encaminhando → SSL ativado), os erros ficam muito mais fáceis de diagnosticar. E, depois que isso vira um “molde”, você consegue repetir o mesmo padrão em qualquer novo projeto, com mais confiança e menos tempo gasto.
A partir daqui, os próximos upgrades naturais são: automatizar rotinas (deploy/health/alertas), reforçar monitoramento e padronizar configs (Nginx + PM2 + envs). Com isso, seu servidor deixa de ser um “ambiente frágil” e vira uma base confiável para aplicações em produção.

