Ir para o conteúdo
Ajuda
Servidor VPS (Cloud)
Servidor VPS (Cloud)

Como hospedar Next.js em VPS com PM2, Nginx e HTTPS

Use este guia com IA

Escolha o que você quer e abra no seu assistente preferido.

1 O que a IA deve fazer?

2 Abrir no assistente

Para agentes
Ver .mdVer .json
Compartilhar

Neste artigo

Resposta rápida: para hospedar Next.js em uma VPS, instale o Node.js LTS, rode npm ci e npm run build, suba a aplicação com PM2 escutando só em 127.0.0.1:3000 e coloque o Nginx na frente com HTTPS do Let's Encrypt. Ative o reinício no boot com pm2 startup e desligue o buffering do Nginx para o streaming funcionar.

next start, standalone ou export: qual usar

ModoComo rodaVantagemQuando usar
next startProcesso Node com o node_modules completoMais simples, igual ao ambiente localBuild feito na própria VPS
output: "standalone"node server.js só com as dependências usadasPasta enxuta, sobe sem npm installBuild no CI ou em Docker
output: "export"HTML estático servido pelo NginxSem Node em produção, consumo mínimoSite sem renderização no servidor, sem rotas de API e sem Server Actions

Este guia cobre os dois primeiros, que mantêm todos os recursos do framework. O export estático merece consideração: landing pages, documentação e blogs ficam mais baratos e rápidos como HTML puro, ao custo de perder rotas de API, Server Actions, ISR e otimização de imagem sem loader externo.

Preparar a VPS: Node.js LTS e PM2

O Next.js 16 exige Node.js 20.9 ou mais novo, mas a linha 20 já saiu de suporte. Use a versão LTS ativa (o Node.js 24 em outubro de 2026), instalada pelo repositório da NodeSource, e mantenha a mesma versão principal no seu computador e na VPS:

Terminal
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
sudo mkdir -p /var/www/meu-site
sudo chown $USER:$USER /var/www/meu-site

Rode tudo com um usuário comum com sudo, nunca como root. A pasta em /var/www evita um problema do Ubuntu 24.04: as pastas pessoais em /home vêm fechadas para outros usuários, e o Nginx não conseguiria ler arquivos de lá.

Importante: o next build consome bem mais memória que o site rodando. Em VPS de 2 GB, crie swap antes do primeiro build, seguindo o guia de swap no Ubuntu, ou o processo morre no meio sem mensagem clara.

Build e variáveis de ambiente

Organize a pasta em três partes: releases guarda cada versão construída, shared guarda o que não muda entre versões (o arquivo de ambiente) e current é um link simbólico para a versão no ar. É essa estrutura que permite atualizar sem derrubar o site.

Terminal
cd /var/www/meu-site
mkdir -p releases shared
nano shared/.env.production
chmod 600 shared/.env.production
git clone https://github.com/sua-conta/meu-site.git releases/v1
cp shared/.env.production releases/v1/
cd releases/v1
npm ci
npm run build
ln -sfn /var/www/meu-site/releases/v1 /var/www/meu-site/current

O npm ci instala as dependências exatamente como estão no lockfile, sem atualizar nada sozinho.

Atenção às variáveis: por padrão, elas só existem no servidor. As que começam com NEXT_PUBLIC_ são copiadas para o JavaScript do navegador durante o build. Trocar uma delas no arquivo e reiniciar não muda nada; é preciso rodar o build de novo.

Modo standalone

Ative a opção no next.config.ts:

Terminal
import type { NextConfig } from "next";

const nextConfig: NextConfig = {
  output: "standalone",
};

export default nextConfig;

O build cria .next/standalone com um server.js. As pastas public e .next/static não são copiadas por padrão, e sem elas o site abre sem CSS, JavaScript e imagens. Copie depois de cada build:

Terminal
cp -r public .next/standalone/
cp -r .next/static .next/standalone/.next/

Se o build acontece no CI, use um executor Linux x64, igual à VPS. A pasta standalone leva binários nativos, como o sharp, e um build feito no Windows ou no macOS copia o binário errado.

Rodar com PM2 e reiniciar no boot

Crie /var/www/meu-site/ecosystem.config.js, fora das versões, apontando para o link current. Para next start:

Terminal
module.exports = {
  apps: [
    {
      name: "meu-site",
      cwd: "/var/www/meu-site/current",
      script: "node_modules/next/dist/bin/next",
      args: "start -H 127.0.0.1 -p 3000",
      instances: 1,
      exec_mode: "fork",
      max_memory_restart: "700M",
      env: { NODE_ENV: "production" },
    },
  ],
};

No modo standalone, o processo é o próprio server.js, que lê porta e endereço das variáveis PORT e HOSTNAME:

Terminal
{
  name: "meu-site",
  cwd: "/var/www/meu-site/current/.next/standalone",
  script: "server.js",
  env: {
    NODE_ENV: "production",
    PORT: "3000",
    HOSTNAME: "127.0.0.1",
  },
}

Inicie, salve a lista de processos e gere o serviço de boot:

Terminal
cd /var/www/meu-site
pm2 start ecosystem.config.js
pm2 save
pm2 startup systemd
# copie e rode a linha com sudo que o comando acima mostrar
curl -I http://127.0.0.1:3000

Escutar em 127.0.0.1 é proposital: a porta 3000 fica inacessível de fora e todo o tráfego passa pelo Nginx. Os logs do PM2 crescem sem limite por padrão; instale a rotação uma vez com pm2 install pm2-logrotate. Comece com uma instância: no modo cluster, cada processo guarda o próprio cache e revalidações de ISR podem não chegar a todos ao mesmo tempo.

Nginx, domínio e HTTPS

Aponte o domínio para o IP da VPS com um registro A para o domínio e outro para o www. Depois instale o Nginx (veja como instalar o Nginx) e crie /etc/nginx/sites-available/meu-site:

Terminal
server {
    listen 80;
    listen [::]:80;
    server_name seu-dominio.com.br www.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";
        proxy_buffering off;
    }
}
  • Cabeçalhos Forwarded: o Next.js usa o host e o protocolo originais para montar URLs e validar Server Actions. Sem eles, formulários podem falhar atrás do proxy.
  • proxy_buffering off: o App Router envia a página em partes (loading e Suspense). Com buffering ligado, o Nginx segura tudo e anula o streaming.
  • client_max_body_size: o padrão do Nginx é 1 MB. Aumente se o site recebe uploads.

Ative o site, libere o firewall e emita o certificado gratuito:

Terminal
sudo ln -s /etc/nginx/sites-available/meu-site /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d seu-dominio.com.br -d www.seu-dominio.com.br
sudo certbot renew --dry-run

O Certbot edita o bloco do Nginx, cria o redirecionamento para HTTPS e agenda a renovação automática. Não é preciso configurar cache dos arquivos estáticos: o Next.js já responde /_next/static com cache de um ano, porque cada nome de arquivo tem um hash do conteúdo.

Atualizar sem derrubar o site

Rodar git pull e npm run build na pasta em uso apaga a .next enquanto o site ainda depende dela, e os visitantes recebem páginas quebradas por minutos. A solução é construir cada versão em outra pasta e só trocar o link no final. Salve como /var/www/meu-site/deploy.sh:

Terminal
#!/usr/bin/env bash
set -euo pipefail
APP=/var/www/meu-site
RELEASE="$APP/releases/$(date +%Y%m%d%H%M%S)"

git clone --depth 1 https://github.com/sua-conta/meu-site.git "$RELEASE"
cp "$APP/shared/.env.production" "$RELEASE/"
cd "$RELEASE"
npm ci
npm run build
ln -sfn "$RELEASE" "$APP/current"
pm2 startOrReload "$APP/ecosystem.config.js" --update-env

# mantém as cinco versões mais recentes para rollback
ls -dt "$APP"/releases/* | tail -n +6 | xargs -r rm -rf

A versão nova é construída enquanto a antiga continua atendendo, e o link current só muda se o build terminar sem erro. No modo standalone, acrescente as duas cópias de pastas depois do build. Para voltar uma versão, aponte o link para a pasta anterior e rode pm2 reload meu-site.

Erros comuns e como resolver

SintomaCausa provávelSolução
Build morre com Killed ou heap out of memoryRAM insuficiente no buildCrie swap, faça o build no CI ou aumente a RAM
Site sem CSS e JavaScript no standalonepublic e .next/static não copiadasCopie as duas pastas depois de cada build
Variável NEXT_PUBLIC_ vazia no navegadorNão estava definida no buildDefina no arquivo e rode o build de novo
502 Bad GatewayProcesso parado ou em outra portaConfira pm2 status e pm2 logs meu-site
Página chega toda de uma vezBuffering do NginxAdicione proxy_buffering off
Failed to find Server Action após deployNavegador com a página da versão anteriorRecarregar resolve; configure deploymentId
Site fora depois de reiniciar a VPSpm2 save ou pm2 startup não executadosRode os dois e teste com um reboot

Qual VPS usar para Next.js na RoxyCloud

A renderização no servidor roda no laço de eventos do Node, que usa um núcleo por processo, então o tempo de resposta de cada página depende muito da velocidade por núcleo. O segundo fator é a RAM do build, quando você compila na própria VPS.

CenárioPlano sugerido
Site pequeno com build feito no CIVPS Ryzen 7 ou Xeon de 2 GB
Build na VPS e SSR com tráfego moderadoVPS Ryzen 7 de 4 GB
Vários sites ou site com banco na mesma VPSVPS Ryzen 9 de 8 GB
Portal ou loja com muito acessoVPS Ryzen 9 de 16 GB

As VPS da RoxyCloud ficam no datacenter próprio em Presidente Prudente (SP), o que reduz o tempo até o primeiro byte para visitantes no Brasil, e todas têm acesso root, NVMe e Anti-DDoS incluso. Compare a VPS Ryzen 7, a VPS Ryzen 9 e a VPS Xeon.

Perguntas frequentes

Next.js funciona completo em uma VPS?

Sim. Com next start, renderização no servidor, ISR, Server Actions e otimização de imagem funcionam sem configuração extra. O que muda é que cache, escala e atualização ficam sob sua responsabilidade.

Qual versão do Node.js usar com Next.js 16?

O mínimo é o Node.js 20.9, mas a linha 20 já saiu de suporte. Use a LTS ativa, que em outubro de 2026 é o Node.js 24, a mesma no seu computador e na VPS.

Preciso de Nginx se o Next.js já é um servidor?

É o recomendado. O Nginx cuida do HTTPS, de conexões lentas e do limite de tamanho de requisição, deixando o Next.js livre para renderizar páginas.

Quanto de RAM o build do Next.js precisa?

Projetos médios costumam passar de 1 GB de pico e podem falhar em VPS de 2 GB sem swap. Com 4 GB o build fica confortável; outra saída é fazer o build no CI e enviar só a pasta standalone.

Devo usar next start ou output standalone?

next start é mais simples quando o build acontece na VPS. O standalone gera uma pasta enxuta, ideal para build no CI ou em Docker. Os dois entregam os mesmos recursos.

Precisa de mais ajuda?

Abra um ticket, entre no Discord ou acesse o painel da RoxyCloud.