---
title: "Como hospedar aplicação Node.js em VPS no Brasil"
description: "Hospede aplicação ou API Node.js em VPS no Brasil: Node 24 LTS, PM2 com reinício automático, Nginx, domínio, HTTPS com Certbot e firewall UFW."
url: "https://streethosting.com.br/guias/vps/hospedar-api-nodejs-vps-brasil"
category: "vps"
slug: "hospedar-api-nodejs-vps-brasil"
datePublished: "2026-06-09"
dateModified: "2026-09-28"
author: "Equipe StreetHosting"
difficulty: "intermediario"
language: "pt-BR"
keywords:
  - "vps nodejs brasil"
  - "hospedar api nodejs"
  - "express vps brasil"
  - "deploy nodejs pm2"
  - "nodejs nginx https vps"
  - "pm2 startup reinicio automatico"
---

# Node.js em produção na VPS: PM2, Nginx, domínio e HTTPS

Aplicação Node.js em produção pede gerenciador de processos, proxy reverso, HTTPS e reinício automático. Veja o passo a passo completo em uma VPS Ubuntu em São Paulo, perto dos seus usuários e das integrações brasileiras.

> **Resposta rápida**
>
> Para **hospedar Node.js em VPS no Brasil**, use uma VPS Ubuntu 24.04 em São Paulo, instale o Node 24 LTS pela NodeSource, rode a aplicação com PM2 escutando em 127.0.0.1, configure o `pm2 startup` para ela voltar depois de um reboot e coloque o Nginx na frente com HTTPS do Let's Encrypt. O firewall libera só SSH, 80 e 443, e APIs leves começam bem com 1 ou 2 vCPU e 2 a 4 GB de RAM.

## Por que hospedar Node.js em VPS no Brasil

Latência importa para apps mobile, integrações PIX e webhooks que conversam com serviços brasileiros. Hospedar em São Paulo reduz o tempo de ida e volta em dezenas de milissegundos comparado a regiões dos EUA, e isso se soma a cada chamada: uma tela que faz cinco requisições em sequência sente a diferença cinco vezes. Usuários percebem o app como mais responsivo, mesmo sem mudar código.

A VPS também dá controle que plataformas prontas não dão: versão exata do Node, processos em segundo plano, WebSockets de longa duração, tarefas agendadas e o banco na mesma rede privada da aplicação, sem cobrança por requisição ou por tempo de execução. Em troca, você cuida do sistema. O resto deste guia mostra como fazer isso com poucas peças e sem deixar portas abertas.

## Stack recomendada

| Peça | Função | Onde escuta |
| --- | --- | --- |
| Node.js 24 LTS | Executa a aplicação | 3000 só no 127.0.0.1 |
| PM2 | Mantém o processo vivo, reinicia em falha, guarda logs | Nenhuma porta |
| systemd | Sobe o PM2 e as aplicações no boot | Nenhuma porta |
| Nginx | Recebe o tráfego, termina o HTTPS e repassa à aplicação | 80 e 443 públicas |
| Certbot | Emite e renova o certificado Let's Encrypt | Usa a porta 80 na validação |
| UFW | Bloqueia tudo que não for SSH, 80 e 443 | Nenhuma porta |

- **Variáveis de ambiente fora do repositório:** senhas e chaves ficam em um `.env` só na VPS, nunca no Git.
- **Logs com rotação:** sem ela, os logs do PM2 crescem até encher o disco.
- **Aplicação invisível para a internet:** ela escuta em 127.0.0.1, e só o Nginx fala com o mundo.

## Instalar Node.js e PM2

Antes de tudo, entre com um usuário comum com sudo e chave SSH, como mostra o guia de [SSH seguro na VPS](https://streethosting.com.br/guias/vps/ssh-seguro-vps-linux). Rodar a aplicação como root significa que qualquer falha nela vira controle total do servidor.

Instale o Node pelo repositório da NodeSource, na linha 24, que é a LTS ativa. O pacote do próprio Ubuntu 24.04 é mais antigo, e o nvm instala o Node dentro da pasta do usuário, o que complica o início automático no boot. Pela NodeSource, o binário fica em `/usr/bin/node`, onde o systemd sempre encontra.

```
curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt install -y nodejs git
node -v
sudo npm install -g pm2
```

Use na VPS a mesma versão major do Node que roda no seu computador e no CI. Diferença de versão é a causa de boa parte dos erros que só aparecem em produção, como dependências nativas compiladas para outra versão.

## Deploy passo a passo

O código fica em `/var/www` com o seu usuário como dono. Clone, instale as dependências e, se o projeto é em TypeScript, compile:

```
sudo mkdir -p /var/www/minha-api
sudo chown usuario:usuario /var/www/minha-api
git clone https://github.com/sua-conta/minha-api.git /var/www/minha-api
cd /var/www/minha-api

# JavaScript puro
npm ci --omit=dev

# TypeScript: precisa das dependências de desenvolvimento para compilar
npm ci
npm run build
npm prune --omit=dev
```

O `npm ci` instala exatamente o que está no `package-lock.json`, sem atualizar nada por conta própria, e por isso é o comando certo para servidor. Depois crie o arquivo de ambiente, legível só pelo seu usuário:

```
nano /var/www/minha-api/.env

NODE_ENV=production
HOST=127.0.0.1
PORT=3000
DATABASE_URL=postgresql://minha_api:troque-esta-senha@127.0.0.1:5432/minha_api

chmod 600 /var/www/minha-api/.env
```

A aplicação precisa ler `HOST` e `PORT` na hora de abrir a porta, por exemplo com `app.listen(process.env.PORT, process.env.HOST)` no Express. Se o código escuta sem informar o endereço, o Node aceita conexões de qualquer interface, e a porta 3000 fica exposta caso o firewall seja desligado por engano.

Por fim, crie uma rota de saúde, como `/health`, que responde 200 quando a aplicação está pronta. Ela serve para conferir cada deploy com um curl e para qualquer monitoramento externo.

## Reinício automático com PM2

Em vez de uma linha solta de `pm2 start`, descreva a aplicação em um arquivo. Assim a configuração fica versionada e qualquer pessoa da equipe sobe o mesmo processo:

```
// /var/www/minha-api/ecosystem.config.js
module.exports = {
  apps: [
    {
      name: "minha-api",
      cwd: "/var/www/minha-api",
      script: "dist/server.js",
      node_args: "--env-file=/var/www/minha-api/.env",
      instances: 1,
      exec_mode: "fork",
      max_memory_restart: "400M",
    },
  ],
};
```

- **node_args com env file:** o próprio Node carrega o `.env` ao iniciar, sem precisar da biblioteca dotenv. Se o seu código já usa dotenv, pode remover essa linha.
- **max_memory_restart:** reinicia o processo se passar do limite, contendo vazamentos de memória antes que afetem o resto da VPS.
- **instances e exec_mode:** o Node usa um núcleo por processo. Com mais vCPUs, o modo cluster com `instances: "max"` sobe um processo por vCPU, desde que a aplicação não guarde estado em memória, como sessões, que precisariam ir para o Redis.

Um detalhe pega muita gente: se o `package.json` tem `"type": "module"`, o Node trata todo arquivo `.js` do projeto como ES module, e o `module.exports` do arquivo do PM2 falha ao carregar. Nesse caso, salve o arquivo como `ecosystem.config.cjs`, que o PM2 também aceita, e use esse nome nos comandos abaixo.

Suba a aplicação e registre o PM2 no systemd:

```
pm2 start /var/www/minha-api/ecosystem.config.js
curl -i http://127.0.0.1:3000/health

pm2 save
pm2 startup systemd
# copie e rode a linha com sudo que o comando acima imprimir

pm2 install pm2-logrotate
```

O `pm2 save` grava a lista de processos atual, e o `pm2 startup` cria o serviço que restaura essa lista no boot. Sem os dois, a aplicação cai no primeiro reinício da VPS e não volta. Teste de verdade com `sudo reboot` antes de considerar pronto. As diferenças entre PM2 e systemd puro estão no guia de [PM2 e systemd na VPS](https://streethosting.com.br/guias/vps/configurar-pm2-startup-systemd-vps).

### Acompanhar a aplicação no dia a dia

O `pm2 status` mostra, para cada processo, tempo no ar, memória e número de reinícios. O `pm2 monit` abre um painel no terminal com CPU e logs em tempo real. Mas nenhum dos dois avisa você quando a VPS inteira fica inacessível. Para isso, configure um monitoramento de uptime externo que chame a rota `/health` pelo domínio a cada minuto e mande alerta quando ela falhar. Ele complementa os logs do PM2 e mede o que o usuário realmente vê, incluindo DNS, certificado e Nginx.

### Atualizar a aplicação

```
cd /var/www/minha-api
git pull origin main
npm ci && npm run build && npm prune --omit=dev
# em JavaScript puro, sem build: npm ci --omit=dev
pm2 reload minha-api
```

No modo cluster, o `pm2 reload` troca os processos um por vez, sem derrubar conexões. No modo fork, com uma instância, ele equivale a um restart, com uma queda de um ou dois segundos. Se você mudou o `ecosystem.config.js`, rode `pm2 startOrReload ecosystem.config.js --update-env` e depois `pm2 save`. Para sites em Next.js, o guia de [Next.js na VPS](https://streethosting.com.br/guias/vps/hospedar-nextjs-vps) usa a mesma base com build em pastas separadas.

## Nginx, domínio e HTTPS

Crie o registro A do domínio, ou de um subdomínio como `api.seu-dominio.com.br`, apontando para o IP da VPS, conforme o guia de [apontar domínio para a VPS](https://streethosting.com.br/guias/vps/apontar-dominio-vps-registro-dns). Depois configure o Nginx como proxy reverso:

```
sudo apt install -y nginx
sudo nano /etc/nginx/sites-available/minha-api

server {
    listen 80;
    listen [::]:80;
    server_name api.seu-dominio.com.br;

    client_max_body_size 10m;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

sudo ln -s /etc/nginx/sites-available/minha-api /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
```

Os cabeçalhos `Upgrade` e `Connection` permitem WebSocket, usado por Socket.IO e similares. Se a API envia eventos por Server Sent Events, acrescente `proxy_buffering off` para que o Nginx não segure as mensagens.

O Nginx espera até 60 segundos pela resposta da aplicação antes de devolver 504 ao cliente. Para uma API típica isso sobra; se alguma rota gera relatórios ou chama serviços lentos, ajuste o `proxy_read_timeout` com base no p95 real dessa rota, com folga, em vez de subir o valor para minutos às cegas. Rotas que demoram muito costumam ser melhor resolvidas com uma fila e uma resposta assíncrona.

Libere o firewall e emita o certificado:

```
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d api.seu-dominio.com.br
sudo certbot renew --dry-run
```

O Certbot cria o bloco HTTPS e o redirecionamento, e o timer do systemd renova o certificado sozinho. Nunca abra a porta 3000 no firewall. Os detalhes estão nos guias de [firewall UFW](https://streethosting.com.br/guias/vps/firewall-ufw-vps-ubuntu) e de [certificado SSL com Nginx](https://streethosting.com.br/guias/vps/certificado-ssl-vps-lets-encrypt-nginx).

> **Atenção**
>
> Atrás do Nginx, o Express enxerga toda requisição vindo de 127.0.0.1. Isso quebra rate limit por IP, logs e cookies seguros. Configure `app.set("trust proxy", "loopback")` no Express, ou `trustProxy: "127.0.0.1"` no Fastify, para confiar só no proxy local.

## Erros comuns e como resolver

| Sintoma | Causa provável | Como resolver |
| --- | --- | --- |
| Error: listen EADDRINUSE | Outro processo já usa a porta 3000 | Veja com sudo ss -tlnp e remova o processo duplicado no PM2 |
| 502 Bad Gateway | Aplicação parada ou escutando em outra porta | Confira pm2 status, pm2 logs e o proxy_pass |
| Aplicação some depois do reboot | pm2 save ou pm2 startup não foram executados | Rode os dois e teste com um reboot |
| Reinícios em sequência no pm2 status | Erro na inicialização ou limite de memória baixo | Leia pm2 logs e revise max_memory_restart |
| Cannot find module depois do deploy | Dependências não instaladas ou build ausente | Rode npm ci e o build antes do reload |
| IP do cliente sempre 127.0.0.1 | Framework sem confiar no proxy | Ative trust proxy apenas para loopback |
| WebSocket não conecta | Cabeçalhos Upgrade ausentes no Nginx | Inclua Upgrade e Connection no bloco location |
| module is not defined in ES module scope | Arquivo do PM2 em .js com type module no projeto | Renomeie para ecosystem.config.cjs |
| 504 Gateway Timeout | Rota mais lenta que o tempo limite do Nginx | Otimize a rota ou ajuste proxy_read_timeout |

Quase todo diagnóstico começa em `pm2 logs minha-api`. Se o PM2 mostra a aplicação online e o erro persiste, a resposta está em `/var/log/nginx/error.log`. Um número de reinícios que só cresce no `pm2 status` é sinal de problema escondido, mesmo que o site pareça no ar.

## Ryzen ou Xeon para Node.js

O Node executa o JavaScript de cada processo em uma única thread, então o clock do processador define quanto tempo cada requisição ocupa o loop de eventos. Por isso a [VPS Ryzen 9 9950X](https://streethosting.com.br/vps/ryzen), com até 5,7 GHz e DDR5, é a indicação principal, principalmente para WebSocket pesado, renderização no servidor e rotas com muito cálculo. APIs I/O bound, que passam a maior parte do tempo esperando banco e serviços externos, com muitas conexões simultâneas, também se saem bem na linha Xeon, que entrega mais vCPU por real para o modo cluster. Compare as duas na página de [planos de VPS](https://streethosting.com.br/vps).

| Cenário | Plano sugerido | Preço mensal |
| --- | --- | --- |
| API leve, webhooks ou integração | Ryzen 1 vCPU, 2 GB DDR5, 20 GB NVMe | R$ 42,00 |
| API com banco na mesma VPS | Ryzen 2 vCPU, 4 GB DDR5, 40 GB NVMe | R$ 70,00 |
| API com tráfego, WebSocket e Redis | Ryzen 4 vCPU, 8 GB DDR5, 80 GB NVMe | R$ 126,00 |
| Muitas conexões I/O bound, orçamento curto | Xeon 3 vCPU, 4 GB DDR4, 40 GB NVMe | R$ 43,00 |

Todos os planos ficam em São Paulo, com AntiDDoS incluso, disco NVMe, acesso root e ativação em até 60 segundos. Se a aplicação crescer, o upgrade pelo painel cobra só a diferença proporcional e exige um reinício da VM; como o PM2 está registrado no boot, a aplicação volta sozinha.

> **Dica**
>
> Registre o p95 de latência antes e depois do deploy. Número concreto convence mais que "está rápido", e serve de base para decidir o próximo upgrade.

- [ ] Node 24 LTS pela NodeSource, mesma versão do desenvolvimento
- [ ] Aplicação escutando só em 127.0.0.1
- [ ] Senhas no .env com permissão 600, fora do Git
- [ ] pm2 save e pm2 startup executados e testados com reboot
- [ ] Rotação de logs do PM2 instalada
- [ ] Rota /health respondendo 200
- [ ] Nginx com HTTPS, trust proxy configurado e UFW ativo
- [ ] Alerta se o PM2 reiniciar mais de 3 vezes por hora

## Perguntas frequentes

### 2 GB de RAM bastam para uma API Node.js pequena?

Sim, para APIs em Express ou Fastify com poucas dependências e tráfego moderado. Deixe margem se usar Prisma, Redis ou workers na mesma VPS, e defina um limite de memória no PM2 para que um vazamento reinicie o processo antes de afetar o resto do sistema.

### Preciso de Docker para rodar Node.js na VPS?

Não obrigatoriamente. PM2 com Nginx resolve bem um ou alguns serviços. Docker ajuda quando há vários microsserviços, versões diferentes de Node na mesma máquina ou um pipeline de CI que já gera imagens.

### Posso deixar a API e o banco de dados na mesma VPS?

Para MVP e projetos pequenos, sim, com o banco escutando só em 127.0.0.1. Quando a carga de disco e o número de conexões crescerem, mover o banco para uma segunda VPS evita que um pico da API derrube o banco, e o contrário.

### PM2 ou systemd para manter o Node.js rodando?

Os dois reiniciam o processo e sobem no boot. O PM2 é mais prático para Node: modo cluster, reload sem queda e logs com poucos comandos. O systemd dispensa dependência extra. Neste guia, o PM2 cuida da aplicação e o systemd sobe o PM2 no boot.

### Por que hospedar a aplicação Node.js em São Paulo?

Porque cada requisição faz ida e volta até o servidor. Para usuários, apps e integrações brasileiras, como PIX e webhooks de serviços nacionais, um servidor em São Paulo corta dezenas de milissegundos por requisição em relação a regiões nos EUA, sem mudar uma linha de código.

## Guias relacionados

- [PM2 ou systemd: manter sua aplicação Node sempre online na VPS](https://streethosting.com.br/guias/vps/configurar-pm2-startup-systemd-vps.md)
- [Como configurar o Nginx como reverse proxy na VPS](https://streethosting.com.br/guias/vps/configurar-nginx-reverse-proxy-vps.md)
- [Como hospedar API FastAPI na VPS com Gunicorn e Nginx](https://streethosting.com.br/guias/vps/hospedar-api-fastapi-vps.md)
- [Como hospedar Next.js na VPS com PM2, Nginx e HTTPS](https://streethosting.com.br/guias/vps/hospedar-nextjs-vps.md)
- [Deploy de bot Discord Node.js com PM2: variáveis de ambiente e restart automático](https://streethosting.com.br/guias/bots-discord/deploy-bot-discord-nodejs-pm2.md)

## Produtos citados

- https://streethosting.com.br/vps/ryzen
- https://streethosting.com.br/vps

## Dados estruturados

```json
[
  {
    "@context": "https://schema.org",
    "@type": [
      "Article",
      "TechArticle"
    ],
    "headline": "Node.js em produção na VPS: PM2, Nginx, domínio e HTTPS",
    "name": "Como hospedar aplicação Node.js em VPS no Brasil",
    "abstract": "Aplicação Node.js em produção pede gerenciador de processos, proxy reverso, HTTPS e reinício automático. Veja o passo a passo completo em uma VPS Ubuntu em São Paulo, perto dos seus usuários e das integrações brasileiras.",
    "description": "Hospede aplicação ou API Node.js em VPS no Brasil: Node 24 LTS, PM2 com reinício automático, Nginx, domínio, HTTPS com Certbot e firewall UFW.",
    "datePublished": "2026-06-09",
    "dateModified": "2026-09-28",
    "author": {
      "@type": "Organization",
      "name": "Equipe StreetHosting"
    },
    "publisher": {
      "@type": "Organization",
      "name": "StreetHosting",
      "url": "https://streethosting.com.br"
    },
    "inLanguage": "pt-BR",
    "mainEntityOfPage": {
      "@type": "WebPage",
      "@id": "https://streethosting.com.br/guias/vps/hospedar-api-nodejs-vps-brasil"
    }
  },
  {
    "@context": "https://schema.org",
    "@type": "FAQPage",
    "mainEntity": [
      {
        "@type": "Question",
        "name": "2 GB de RAM bastam para uma API Node.js pequena?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Sim, para APIs em Express ou Fastify com poucas dependências e tráfego moderado. Deixe margem se usar Prisma, Redis ou workers na mesma VPS, e defina um limite de memória no PM2 para que um vazamento reinicie o processo antes de afetar o resto do sistema."
        }
      },
      {
        "@type": "Question",
        "name": "Preciso de Docker para rodar Node.js na VPS?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Não obrigatoriamente. PM2 com Nginx resolve bem um ou alguns serviços. Docker ajuda quando há vários microsserviços, versões diferentes de Node na mesma máquina ou um pipeline de CI que já gera imagens."
        }
      },
      {
        "@type": "Question",
        "name": "Posso deixar a API e o banco de dados na mesma VPS?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Para MVP e projetos pequenos, sim, com o banco escutando só em 127.0.0.1. Quando a carga de disco e o número de conexões crescerem, mover o banco para uma segunda VPS evita que um pico da API derrube o banco, e o contrário."
        }
      },
      {
        "@type": "Question",
        "name": "PM2 ou systemd para manter o Node.js rodando?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Os dois reiniciam o processo e sobem no boot. O PM2 é mais prático para Node: modo cluster, reload sem queda e logs com poucos comandos. O systemd dispensa dependência extra. Neste guia, o PM2 cuida da aplicação e o systemd sobe o PM2 no boot."
        }
      },
      {
        "@type": "Question",
        "name": "Por que hospedar a aplicação Node.js em São Paulo?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Porque cada requisição faz ida e volta até o servidor. Para usuários, apps e integrações brasileiras, como PIX e webhooks de serviços nacionais, um servidor em São Paulo corta dezenas de milissegundos por requisição em relação a regiões nos EUA, sem mudar uma linha de código."
        }
      }
    ]
  }
]
```
