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
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
| Modo | Como roda | Vantagem | Quando usar |
|---|---|---|---|
next start | Processo Node com o node_modules completo | Mais simples, igual ao ambiente local | Build feito na própria VPS |
output: "standalone" | node server.js só com as dependências usadas | Pasta enxuta, sobe sem npm install | Build no CI ou em Docker |
output: "export" | HTML estático servido pelo Nginx | Sem Node em produção, consumo mínimo | Site 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:
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-siteRode 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 buildconsome 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.
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/currentO 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:
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:
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:
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:
{
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:
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:3000Escutar 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:
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:
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-runO 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:
#!/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 -rfA 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
| Sintoma | Causa provável | Solução |
|---|---|---|
| Build morre com Killed ou heap out of memory | RAM insuficiente no build | Crie swap, faça o build no CI ou aumente a RAM |
| Site sem CSS e JavaScript no standalone | public e .next/static não copiadas | Copie as duas pastas depois de cada build |
Variável NEXT_PUBLIC_ vazia no navegador | Não estava definida no build | Defina no arquivo e rode o build de novo |
| 502 Bad Gateway | Processo parado ou em outra porta | Confira pm2 status e pm2 logs meu-site |
| Página chega toda de uma vez | Buffering do Nginx | Adicione proxy_buffering off |
| Failed to find Server Action após deploy | Navegador com a página da versão anterior | Recarregar resolve; configure deploymentId |
| Site fora depois de reiniciar a VPS | pm2 save ou pm2 startup não executados | Rode 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ário | Plano sugerido |
|---|---|
| Site pequeno com build feito no CI | VPS Ryzen 7 ou Xeon de 2 GB |
| Build na VPS e SSR com tráfego moderado | VPS Ryzen 7 de 4 GB |
| Vários sites ou site com banco na mesma VPS | VPS Ryzen 9 de 8 GB |
| Portal ou loja com muito acesso | VPS 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.