Auto-hospedagem de Next.js com OpenNext em 2025: Um Guia Completo

Venho rodando Next.js em produção desde a versão 9. Durante a maior parte desse tempo, Vercel era a escolha óbvia — fazer deploy, esquecer, seguir em frente. Mas em algum momento de 2024, as faturas começaram a parecer parcelas de carro. Quando sua conta de hospedagem para um site de marketing ultrapassa seus custos reais de infraestrutura em nuvem, algo está quebrado. Foi aí que comecei a investigar OpenNext, e depois de migrar três aplicações em produção para longe de Vercel no último ano, tenho opiniões.

Este não é um artigo "Vercel é ruim". Vercel é genuinamente excelente. Mas não é mais a única opção, e para muitos times, não é a certa. Deixa eu te levar através de tudo o que aprendi sobre auto-hospedagem de Next.js com OpenNext — o bom, o feio e o surpreendentemente acessível.

Índice

OpenNext: Auto-hospede Next.js em AWS, Cloudflare ou VPS Sem Vercel

O que é OpenNext e Por Que Existe

Next.js foi desenhado para rodar em Vercel. Não é teoria da conspiração — é arquitetura. Features como ISR (Incremental Static Regeneration), middleware, otimização de imagens e server actions têm implementações específicas de Vercel embutidas. Quando você tenta fazer next start em um servidor aleatório, você consegue apenas um subconjunto do que Next.js pode fazer.

OpenNext é um adaptador open-source que pega seu output de build de Next.js e o transforma em pacotes de deployment que funcionam em outras plataformas. Começou como um projeto da comunidade SST focado em AWS Lambda, mas a partir da v3 (a versão principal atual em 2025), suporta múltiplos alvos de deployment incluindo Cloudflare Workers, servidores Node.js tradicionais e mais.

Aqui está o que OpenNext realmente faz:

  • ISR e revalidação — O sistema de revalidação baseado em tags que Vercel implementa com sua infraestrutura interna? OpenNext a recria usando DynamoDB + SQS em AWS, ou KV stores em Cloudflare.
  • Otimização de imagens — O componente <Image> de Next.js depende de uma API de otimização. OpenNext empacota um otimizador baseado em Sharp ou roteia para soluções específicas de plataforma.
  • Middleware — Roda na edge em Vercel. OpenNext mapeia isso para CloudFront Functions, Cloudflare Workers, ou roda in-process em VPS.
  • Server actions — Suporte completo, roteado através da função de servidor apropriada.
  • Streaming e partial prerendering — O suporte amadureceu significativamente em OpenNext v3.x.

O que OpenNext Não É

Não é uma plataforma de hospedagem. Não é uma CDN. É um adaptador de build — uma camada de tradução entre o output de Next.js e sua infraestrutura. Você ainda precisa de fato rodar a coisa em algum lugar.

O Cenário de Auto-hospedagem em 2025-2026

O ecossistema explodiu desde que comecei a olhar para isso. Aqui está como as coisas estão:

Plataforma Suporte OpenNext Maturidade Melhor Para
AWS (via SST) Primeira classe Pronto para produção Times já em AWS
Cloudflare Workers Adaptador oficial Estável (alguns edge cases) Apps edge-first, otimização de custo
Docker/VPS Community + oficial Estável Deploys simples, infra existente
Kubernetes Community Helm charts Amadurecendo Enterprise, clusters K8s existentes
Netlify Built-in (próprio adaptador) Pronto para produção Times comprometidos com Netlify
Google Cloud Run Community Experimental Lojas GCP

Os dois caminhos que pessoalmente testei em produção e posso garantir são AWS via SST e Docker em VPS. Cloudflare é o calouro empolgante que está melhorando mensalmente.

Alvo de Deploy: AWS com SST

Este é o caminho dourado. SST (Serverless Stack) tem suporte embutido a Next.js alimentado por OpenNext, e é onde o maior esforço de engenharia foi.

Visão Geral da Arquitetura

Quando você faz deploy de Next.js via SST em AWS, aqui está o que é criado:

  • Distribuição CloudFront — Seu CDN, manipula ativos estáticos e roteamento
  • Função(ões) Lambda — Renderização do lado do servidor, rotas de API, server actions
  • Bucket S3 — Ativos estáticos, páginas pré-renderizadas, cache ISR
  • Tabela DynamoDB — Mapeamento de tags ISR para revalidação
  • Fila SQS — Processamento de revalidação assíncrono
  • CloudFront Function ou Lambda@Edge — Execução de middleware

Parece muita coisa. É. Mas SST abstrai tudo em cerca de 20 linhas de config.

Configuração SST

Aqui está um real sst.config.ts de um dos meus projetos em produção:

/// <reference path="./.sst/platform/config.d.ts" />

export default $config({
  app(input) {
    return {
      name: "my-nextjs-app",
      removal: input.stage === "production" ? "retain" : "remove",
      home: "aws",
      providers: {
        aws: {
          region: "us-east-1",
        },
      },
    };
  },
  async run() {
    const site = new sst.aws.Nextjs("Site", {
      domain: {
        name: "myapp.com",
        dns: sst.aws.dns(),
      },
      warm: 5, // manter 5 instâncias Lambda quentes
      memory: "1024 MB",
      environment: {
        DATABASE_URL: process.env.DATABASE_URL!,
        NEXT_PUBLIC_API_URL: "https://api.myapp.com",
      },
    });

    return {
      url: site.url,
    };
  },
});

Depois faça deploy:

npx sst deploy --stage production

O primeiro deploy leva 8-12 minutos (propagação de distribuição CloudFront). Deploys subsequentes levam 2-4 minutos.

Considerações Lambda

O maior gotcha com hospedagem baseada em Lambda é cold starts. As funções de servidor Next.js não são pequenas — você está olhando para bundles de 20-80MB dependendo de suas dependências. Cold starts variam de 800ms a 3 segundos.

Mitigações que usei:

  1. Concorrência provisionada — O parâmetro warm do SST mantém instâncias quentes. A $0.0000041667 por GB-segundo, manter 5 instâncias de uma função de 1GB quentes custa ~$15/mês.
  2. Bundles menores — Audite suas dependências do lado do servidor. Encontrei um projeto importando lodash do lado do servidor quando precisávamos apenas de lodash/get. O bundle caiu de 68MB para 31MB.
  3. Deploy regional — Não use Lambda@Edge para SSR a menos que seja absolutamente necessário. Lambda de região única com cache CloudFront é ótimo para 95% dos apps.

OpenNext: Auto-hospede Next.js em AWS, Cloudflare ou VPS Sem Vercel - arquitetura

Alvo de Deploy: Cloudflare Workers

Cloudflare tem feito movimentos sérios. Seu runtime Workers agora suporta APIs de Node.js suficientes para Next.js rodar lá, e o adaptador OpenNext Cloudflare ficou notavelmente estável.

Setup com OpenNext Cloudflare

npm install @opennext/cloudflare

Adicione ao seu wrangler.toml:

name = "my-nextjs-app"
main = ".open-next/worker.js"
compatibility_date = "2025-01-01"
compatibility_flags = ["nodejs_compat_v2"]

[assets]
directory = ".open-next/assets"
binding = "ASSETS"

[[kv_namespaces]]
binding = "NEXT_CACHE_KV"
id = "your-kv-namespace-id"

Build e deploy:

npx @opennext/cloudflare build
npx wrangler deploy

Os Trade-offs de Cloudflare

Pros:

  • Sem cold starts — Workers ligam em menos de 5ms globalmente
  • Edge global por padrão — Seu SSR roda em 300+ locais
  • Preços absurdos — $5/mês para 10 milhões de requisições no plano pago

Contras:

  • Limites de memória — 128MB no gratuito, 256MB no pago. Apps Next.js grandes podem atingir isso.
  • Limites de CPU time — 30 segundos no plano pago. Páginas SSR pesadas podem ser um problema.
  • Gaps de compatibilidade Node.js — A maioria das coisas funciona, mas se você está usando módulos Node nativos como sharp diretamente, precisará de workarounds. Cloudflare Images pode lidar com otimização em vez disso.
  • Alguns features de Next.js não são suportados — No início de 2025, suporte a partial prerendering ainda é experimental em Cloudflare.

Para sites com muito conteúdo e landing pages, Cloudflare Workers é incrivelmente convincente. Para aplicações web complexas com lógica pesada do lado do servidor, ainda inclinaria-me para AWS ou Docker.

Alvo de Deploy: VPS com Docker

Às vezes você só quer um servidor. Nenhuma função Lambda, nenhum runtime de edge, nenhum diagrama de arquitetura com 47 serviços. Uma box que roda seu código. Respeito isso.

O Dockerfile

Aqui está o Dockerfile de produção que uso. É multi-stage, otimizado e realmente funciona:

# Stage 1: Dependências
FROM node:20-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable pnpm && pnpm install --frozen-lockfile

# Stage 2: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

ENV NEXT_TELEMETRY_DISABLED=1
ENV NODE_ENV=production

RUN corepack enable pnpm && pnpm build

# Stage 3: Produção
FROM node:20-alpine AS runner
WORKDIR /app

ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"

CMD ["node", "server.js"]

Crítico: você precisa de output: 'standalone' no seu next.config.js:

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'standalone',
};

module.exports = nextConfig;

Recomendações VPS

Rodei esse setup em vários provedores:

Provedor Spec Custo Mensal Notas
Hetzner CAX21 4 vCPU ARM, 8GB RAM €7.49 (~$8) Melhor valor, datacenters EU
DigitalOcean Droplet 2 vCPU, 4GB RAM $24 Boa cobertura US
Fly.io (machine) 2 vCPU, 4GB RAM ~$30 Auto-scaling, regiões globais
Railway Baseado em uso $5-50 Setup mais fácil, DX tipo Vercel
AWS EC2 t4g.medium 2 vCPU, 4GB RAM ~$25 Já em AWS

Para um deployment Docker direto, Hetzner é absurdamente bom valor. Rodo um app Next.js servindo 2M+ pageviews/mês em uma instância ARM da Hetzner por €7.49 atrás do nível gratuito de Cloudflare. O servidor nem suça.

O Que Você Perde com Docker/VPS

Vamos ser honestos sobre o que next start em um VPS não te dá comparado com Vercel ou o setup SST:

  • Revalidação ISR é básica — Cache apenas de sistema de arquivos. Sem cache distribuído entre múltiplas instâncias. Se você está rodando um servidor único, tudo bem. Multi-servidor? Você precisa de Redis ou uma camada de cache compartilhada.
  • Sem middleware de edge — Middleware roda in-process, que é totalmente okay para a maioria dos casos de uso.
  • Otimização de imagens — Funciona via Sharp, mas você está servindo imagens otimizadas de sua origem única. Coloque Cloudflare ou um CDN na frente.
  • Sem deploys atômicos — Você precisa lidar com deploys zero-downtime você mesmo (Docker Compose com health checks, ou um reverse proxy como Caddy/Traefik).

Para a maioria dos apps da Social Animal, especialmente as builds de headless CMS que fazemos através de nosso trabalho de desenvolvimento de headless CMS, um único VPS com um CDN na frente é perfeitamente adequado.

Comparação de Custos: Vercel vs Auto-hospedagem

Vamos falar de dinheiro. Isso é baseado em dados reais de faturamento de um app Next.js fazendo ~5M requisições/mês com ISR, otimização de imagens e renderização moderada do lado do servidor.

Fator de Custo Vercel Pro Vercel Enterprise AWS/SST Cloudflare Hetzner VPS
Plataforma base $20/usuário/mês Custom (~$3k+/mês) $0 $5/mês €7.49/mês
Compute/requisições $150-400/mês Incluído $40-80/mês $0-15/mês Incluído
Bandwidth (100GB) Incluído Incluído $8.50 (CloudFront) Incluído Incluído
Otimização de imagens $50-200/mês Incluído $5-15/mês (Lambda) $5/mês (CF Images) Incluído (Sharp)
ISR/Cache Incluído Incluído $2-5/mês (DynamoDB) $0-5/mês (KV) $0
Total Estimado $300-700/mês $3,000+/mês $55-110/mês $10-25/mês $8-15/mês

Esses números de Vercel não são hipotéticos. Vi as faturas. Os preços por assento, overages de execução de função e cobranças de bandwidth no tier Pro somam rápido para times de 5+.

Os números de AWS/SST assumem tráfego moderado com concorrência provisionada. O preço de Cloudflare é genuinamente selvagem — é difícil gastar dinheiro real lá a menos que você esteja fazendo algo exótico.

Quando Sair de Vercel

Não saia apenas porque pode. Saia porque deveria. Aqui está meu framework:

Fique em Vercel se:

  • Seu time é pequeno (1-3 devs) e o tempo de dev é seu recurso mais caro
  • Você está gastando menos de $100/mês em Vercel
  • Você não tem ninguém que gosta de trabalho de infraestrutura
  • Você está iterando rápido e precisa de previews instantâneos para cada PR
  • Você está usando features específicas de Vercel como Analytics, Speed Insights ou integrações do Vercel AI SDK

Saia de Vercel se:

  • Fatura mensal ultrapassa $500 e crescendo
  • Você precisa de infraestrutura em regiões específicas para compliance (GDPR, residência de dados)
  • Você já está rodando infraestrutura significativa em AWS/GCP/Cloudflare
  • Cold starts em serverless são inaceitáveis para seu caso de uso
  • Você precisa de estratégias de cache customizadas que não se encaixam no modelo de Vercel
  • Você atingiu os limites de tamanho de função ou tempo de execução de Vercel

Considere seriamente sair se:

  • Você está em preço Vercel Enterprise e o contrato renewal chegou
  • Seu app é principalmente estático/ISR e você está pagando preços de SSR dinâmico
  • Você quer rodar seu frontend junto de seu backend na mesma infraestrutura

O Playbook de Migração

Fiz isso três vezes agora. Aqui está o processo que sigo, refinado através de experiência dolorosa.

Passo 1: Audite Seus Features de Next.js

Antes de tocar em qualquer coisa, catalogue quais features de Next.js você realmente usa:

# Encontre middleware
find . -name "middleware.ts" -o -name "middleware.js"

# Encontre rotas de API
find ./app -name "route.ts" -o -name "route.js" | head -20

# Procure por ISR
grep -r "revalidate" ./app --include="*.ts" --include="*.tsx" | head -20

# Procure por server actions
grep -r "use server" ./app --include="*.ts" --include="*.tsx" | head -20

# Procure next.config por features especiais
cat next.config.js

Passo 2: Escolha Seu Alvo

Baseado na auditoria:

  • ISR pesado + middleware + otimização de imagens → AWS/SST
  • SSR simples + site de conteúdo → Cloudflare ou VPS
  • Já tenho infraestrutura Docker/K8s → VPS/Docker
  • Precisa estar pronto até sexta → Docker em Railway ou Fly.io

Se você está construindo com Next.js ou Astro, a escolha de plataforma de alvo impacta significativamente suas decisões de arquitetura.

Passo 3: Configure CI/CD

O CI/CD de Vercel é genuinamente ótimo. Você sentirá falta. Replique com GitHub Actions:

# .github/workflows/deploy.yml
name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v4
        with:
          version: 9

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'pnpm'

      - run: pnpm install --frozen-lockfile
      - run: pnpm build
      - run: pnpm test

      # Para SST:
      - run: npx sst deploy --stage production
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

      # Para Docker/VPS (alternativa):
      # - run: docker build -t myapp .
      # - run: docker push registry.example.com/myapp:latest
      # - run: ssh deploy@server 'cd /app && docker compose pull && docker compose up -d'

Passo 4: Deployments de Preview

Essa é a coisa que pessoas perdem mais de Vercel. Para SST, use stages:

# No seu workflow CI de PR
npx sst deploy --stage pr-${{ github.event.pull_request.number }}

Para Docker, ferramentas como Coolify (self-hosted) ou Railway lidam bem com deployments de preview.

Passo 5: DNS Cutover

O momento real da migração. Sempre recomendo:

  1. Faça deploy em nova infraestrutura junto de Vercel
  2. Teste a fundo com um domínio de staging
  3. Abaixe TTL de DNS para 60 segundos um dia antes
  4. Corte DNS durante horas de baixo tráfego
  5. Mantenha deployment de Vercel rodando por 48 horas como fallback
  6. Monitore taxas de erro, TTFB e Core Web Vitals de perto

Passo 6: Desmantle Vercel

Uma vez que estiver confiante (dê pelo menos uma semana), cancele a assinatura de Vercel e remova o projeto. Não deixe projetos zumbis acumulando cobranças.

Armadilhas Comuns e Como Evitá-las

Variáveis de ambiente desaparecendo. Next.js tem vars prefixadas com NEXT_PUBLIC_ (embutidas em tempo de build) e vars somente de servidor (disponíveis em runtime). Em Vercel, essa distinção é de certa forma borrada. Em self-hosted, é estrita. Garanta que todas as vars NEXT_PUBLIC_ estejam disponíveis em tempo de build em seu CI.

Cache ISR não persiste. Em Docker, o diretório .next/cache precisa estar em um volume persistente. Senão, todo reinício de container perde suas páginas em cache:

# docker-compose.yml
services:
  web:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - next-cache:/app/.next/cache

volumes:
  next-cache:

Falhas na instalação de Sharp. A biblioteca sharp de otimização de imagens precisa de binários específicos de plataforma. Em Docker, garanta que você está instalando dependências dentro da mesma arquitetura que seu runtime. O Dockerfile acima lida com isso usando builds multi-stage com a mesma imagem base.

Diferenças de comportamento de Middleware. Vercel roda middleware em sua rede de edge. Em AWS/SST, roda como uma CloudFront Function (limitada a 10ms de execução, 2MB de tamanho). Middleware complexo pode precisar ser movido para a função de servidor. Tive que refatorar middleware de auth por causa desses limites.

Headers e rewrites faltando. Se você estava contando com vercel.json para headers, redirects ou rewrites, você precisa mover esses para next.config.js ou sua configuração de CDN/reverse proxy.

Se qualquer coisa disso parece avassaladora, é exatamente o tipo de trabalho de infraestrutura que fazemos na Social Animal. Procure nossa página de preços ou nos contacte — fizemos essas migrações suficientes vezes para ter um processo refinado.

FAQ

OpenNext é production-ready em 2025? Sim. OpenNext v3.x está rodando cargas de produção para milhares de empresas. O caminho SST/AWS é o mais testado em produção, com suporte de Cloudflare próximo atrás. Não chamaria suporte para Google Cloud ou Kubernetes bare de maduro ainda, mas AWS e Cloudflare são sólidos.

OpenNext suporta Next.js App Router e Server Components? Suporte completo. App Router, Server Components, Server Actions, streaming e Suspense tudo funciona. O time de OpenNext rastreia releases de Next.js de perto, embora típicamente haja um lag de 1-3 semanas depois de versões maiores de Next.js antes de OpenNext acompanhar.

Quanto eu posso realmente economizar saindo de Vercel? Depende muito dos seus padrões de uso. Para um time de 5 desenvolvedores rodando um app de tráfego moderado, vi times irem de $600-800/mês em Vercel Pro para $30-80/mês em AWS/SST ou menos de $20/mês em um VPS. As economias são reais mas também é o burden adicional de manutenção.

Posso usar ISR (Incremental Static Regeneration) sem Vercel? Absolutamente. Em AWS/SST, ISR usa DynamoDB para o cache de tag e SQS para revalidação assíncrona — é completamente funcional incluindo revalidação on-demand via revalidateTag() e revalidatePath(). Em um VPS, ISR funciona com o cache de sistema de arquivos, que é ótimo para deployments de servidor único.

E quanto aos deployments de preview de Vercel? Posso replicar esses? Você consegue 80% da experiência. SST suporta deployments baseados em stage, então cada PR pode conseguir seu próprio stack. Coolify e ferramentas similares oferecem deployments de preview para setups baseados em Docker. O que você não facilmente replicará é o sistema de comentários visuais de Vercel e a integração GitHub apertada para status de deployment. A maioria dos times acha o tradeoff aceitável.

Deveria usar OpenNext com Cloudflare ou AWS para um site de headless CMS? Para sites de headless CMS com muito conteúdo (Sanity, Contentful, Storyblok), Cloudflare Workers é uma excelente escolha. Esses sites tendem a ser pesados em ISR com lógica relativa de servidor leve — perfeito para o modelo de preço de Cloudflare. Só iria AWS se você precisar de features que Cloudflare ainda não suporta ou se você já estiver profundo no ecossistema AWS.

É mais difícil auto-hospedar Next.js do que auto-hospedar Astro ou Remix? Honestamente? Sim. Next.js tem o output de build mais complexo de qualquer framework por causa de features como ISR, middleware, otimização de imagens e partial prerendering. Astro e Remix têm histórias de deployment muito mais simples. Se você está iniciando um novo projeto e auto-hospedagem é uma prioridade, considere Astro — é dramaticamente mais simples de hospedar. Mas se você já está em Next.js, OpenNext torna migração prática.

O que acontece se OpenNext parar de ser mantido? OpenNext é apoiado por SST e tem uma comunidade ativa com major sponsors. Dito isso, essa é uma preocupação legítima para qualquer dependência open-source. A mitigação é que a abordagem Docker/standalone (next start) funciona sem OpenNext em tudo — você apenas perde alguns dos features mais avançados como revalidação de tag ISR e middleware de edge. É uma degradação graciosa, não um cliff.