He estado ejecutando Next.js en producción desde la versión 9. Durante la mayor parte de ese tiempo, Vercel era la opción obvia — desplegar, olvidar, seguir adelante. Pero en algún momento alrededor de 2024, las facturas comenzaron a parecer pagos de automóvil. Cuando tu factura de hosting para un sitio de marketing supera tus costos reales de infraestructura en la nube, algo está roto. Fue entonces cuando comencé a investigar OpenNext, y después de migrar tres aplicaciones de producción fuera de Vercel en el año pasado, tengo opiniones.

Este no es un artículo "Vercel es malo". Vercel es genuinamente excelente. Pero ya no es la única opción, y para muchos equipos, no es la correcta. Déjame mostrarte todo lo que he aprendido sobre auto-hosting de Next.js con OpenNext — lo bueno, lo feo y lo sorprendentemente asequible.

Tabla de Contenidos

OpenNext: Auto-alojar Next.js en AWS, Cloudflare o VPS sin Vercel

¿Qué es OpenNext y por qué existe?

Next.js fue diseñado para ejecutarse en Vercel. Eso no es una conspiración — es arquitectura. Características como ISR (Incremental Static Regeneration), middleware, optimización de imágenes y acciones de servidor tienen implementaciones específicas de Vercel incorporadas. Cuando intentas next start en un servidor aleatorio, obtienes un subconjunto de lo que Next.js puede hacer.

OpenNext es un adaptador de código abierto que toma tu salida de compilación de Next.js y la transforma en paquetes de despliegue que funcionan en otras plataformas. Comenzó como un proyecto comunitario de SST enfocado en AWS Lambda, pero a partir de v3 (la versión principal actual en 2025), admite múltiples objetivos de despliegue incluyendo Cloudflare Workers, servidores Node.js tradicionales y más.

Aquí está lo que OpenNext realmente maneja:

  • ISR y revalidación — El sistema de revalidación basado en etiquetas que Vercel implementa con su infraestructura interna. ¿OpenNext lo recrea usando DynamoDB + SQS en AWS, o almacenes KV en Cloudflare.
  • Optimización de imágenes — El componente <Image> de Next.js depende de una API de optimización. OpenNext empaqueta un optimizador basado en Sharp o enruta a soluciones específicas de plataforma.
  • Middleware — Se ejecuta en el edge en Vercel. OpenNext lo asigna a CloudFront Functions, Cloudflare Workers, o lo ejecuta en-proceso en VPS.
  • Acciones de servidor — Soporte completo, enrutado a través de la función de servidor apropiada.
  • Streaming y pre-renderización parcial — El soporte ha madurado significativamente en OpenNext v3.x.

Lo que OpenNext NO es

No es una plataforma de hosting. No es un CDN. Es un adaptador de compilación — una capa de traducción entre la salida de Next.js y tu infraestructura. Aún necesitas ejecutar la cosa en algún lugar.

El panorama del auto-hosting en 2025-2026

El ecosistema ha explotado desde que comencé a mirar esto. Aquí está dónde están las cosas:

Plataforma Soporte de OpenNext Madurez Mejor para
AWS (vía SST) Primera clase Listo para producción Equipos ya en AWS
Cloudflare Workers Adaptador oficial Estable (algunos casos especiales) Aplicaciones edge-first, optimización de costos
Docker/VPS Comunidad + oficial Estable Despliegues simples, infraestructura existente
Kubernetes Helm charts comunitarios Madurando Empresarial, clusters K8s existentes
Netlify Adaptador propio integrado Listo para producción Equipos comprometidos con Netlify
Google Cloud Run Comunitario Experimental Empresas de GCP

Los dos caminos que he probado personalmente en batalla y puedo avalar son AWS vía SST y Docker en un VPS. Cloudflare es el recién llegado emocionante que mejora mensualmente.

Objetivo de despliegue: AWS con SST

Este es el camino dorado. SST (Serverless Stack) tiene soporte integrado de Next.js impulsado por OpenNext, y es donde ha ido el mayor esfuerzo de ingeniería.

Descripción general de la arquitectura

Cuando despliegas Next.js vía SST en AWS, aquí está lo que se crea:

  • Distribución CloudFront — Tu CDN, maneja activos estáticos y enrutamiento
  • Función Lambda — Renderización del lado del servidor, rutas API, acciones de servidor
  • Bucket S3 — Activos estáticos, páginas pre-renderizadas, caché ISR
  • Tabla DynamoDB — Mapeo de etiquetas ISR para revalidación
  • Cola SQS — Procesamiento de revalidación asincrónico
  • CloudFront Function o Lambda@Edge — Ejecución de middleware

Suena como mucho. Lo es. Pero SST lo abstrae todo en aproximadamente 20 líneas de configuración.

Configuración de SST

Aquí está una sst.config.ts real de uno de mis proyectos de producción:

/// <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, // mantener 5 instancias Lambda calientes
      memory: "1024 MB",
      environment: {
        DATABASE_URL: process.env.DATABASE_URL!,
        NEXT_PUBLIC_API_URL: "https://api.myapp.com",
      },
    });

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

Luego desplega:

npx sst deploy --stage production

El primer despliegue toma 8-12 minutos (propagación de distribución CloudFront). Los despliegues posteriores son 2-4 minutos.

Consideraciones de Lambda

El mayor problema con el hosting basado en Lambda son los cold starts. Las funciones de servidor de Next.js no son pequeñas — estás viendo paquetes de 20-80MB dependiendo de tus dependencias. Los cold starts oscilan entre 800ms y 3 segundos.

Mitigaciones que he usado:

  1. Concurrencia provisionada — El parámetro warm de SST mantiene las instancias calientes. A $0.0000041667 por GB-segundo, mantener 5 instancias de una función de 1GB calientes cuesta ~$15/mes.
  2. Paquetes más pequeños — Audita tus dependencias del lado del servidor. Encontré un proyecto importando lodash del lado del servidor cuando solo necesitábamos lodash/get. El paquete bajó de 68MB a 31MB.
  3. Despliegue regional — No uses Lambda@Edge para SSR a menos que absolutamente lo necesites. Lambda de una sola región con almacenamiento en caché de CloudFront es suficiente para el 95% de las aplicaciones.

OpenNext: Auto-alojar Next.js en AWS, Cloudflare o VPS sin Vercel - arquitectura

Objetivo de despliegue: Cloudflare Workers

Cloudflare ha estado haciendo movimientos serios. Su tiempo de ejecución de Workers ahora admite suficientes APIs de Node.js que Next.js puede ejecutarse realmente allí, y el adaptador Cloudflare de OpenNext se ha vuelto notablemente estable.

Configuración con OpenNext Cloudflare

npm install @opennext/cloudflare

Añade a tu 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"

Compila y desplega:

npx @opennext/cloudflare build
npx wrangler deploy

Los compromisos de Cloudflare

Pros:

  • Sin cold starts — Los Workers se inician en menos de 5ms globalmente
  • Edge global por defecto — Tu SSR se ejecuta en 300+ ubicaciones
  • Precios absurdos — $5/mes para 10 millones de solicitudes en el plan de pago

Contras:

  • Límites de memoria — 128MB en gratuito, 256MB en pago. Las aplicaciones grandes de Next.js pueden alcanzar esto.
  • Límites de tiempo de CPU — 30 segundos en plan de pago. Las páginas SSR pesadas pueden ser un problema.
  • Brechas de compatibilidad de Node.js — La mayoría de las cosas funcionan, pero si estás usando módulos nativos de Node como sharp directamente, necesitarás soluciones alternas. Cloudflare Images puede manejar la optimización en su lugar.
  • Algunas características de Next.js no están soportadas — A principios de 2025, el soporte de pre-renderización parcial aún es experimental en Cloudflare.

Para sitios ricos en contenido y páginas de marketing, Cloudflare Workers es increíblemente convincente. Para aplicaciones web complejas con lógica pesada del lado del servidor, aún me inclinaría hacia AWS o Docker.

Objetivo de despliegue: VPS con Docker

A veces solo quieres un servidor. Sin funciones Lambda, sin tiempo de ejecución edge, sin diagrama de arquitectura de 47 servicios. Una caja que ejecuta tu código. Respeto eso.

El Dockerfile

Aquí está el Dockerfile de producción que uso. Es multi-etapa, optimizado, y realmente funciona:

# Etapa 1: Dependencias
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

# Etapa 2: Compilación
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

# Etapa 3: Producción
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: necesitas output: 'standalone' en tu next.config.js:

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

module.exports = nextConfig;

Recomendaciones de VPS

He ejecutado esta configuración en varios proveedores:

Proveedor Especificación Costo Mensual Notas
Hetzner CAX21 4 vCPU ARM, 8GB RAM €7.49 (~$8) Mejor valor, centros de datos EU
DigitalOcean Droplet 2 vCPU, 4GB RAM $24 Buena cobertura US
Fly.io (máquina) 2 vCPU, 4GB RAM ~$30 Auto-escalado, regiones globales
Railway Basado en uso $5-50 Configuración más fácil, DX tipo Vercel
AWS EC2 t4g.medium 2 vCPU, 4GB RAM ~$25 Ya en AWS

Para un despliegue directo con Docker, Hetzner tiene una relación precio-valor absurdamente buena. Ejecuto una aplicación Next.js sirviendo 2M+ vistas de página/mes en una instancia ARM de Hetzner de €7.49 detrás del nivel gratuito de CDN de Cloudflare. El servidor apenas transpira.

Lo que pierdes con Docker/VPS

Seamos honestos sobre lo que next start en un VPS no te da en comparación con Vercel o la configuración de SST:

  • La revalidación ISR es básica — Solo caché del sistema de archivos. Sin caché distribuido en múltiples instancias. Si estás ejecutando un único servidor, esto está bien. ¿Múltiples servidores? Necesitas Redis o una capa de caché compartida.
  • Sin middleware edge — El middleware se ejecuta en-proceso, que es perfectamente bien para la mayoría de casos de uso.
  • Optimización de imágenes — Funciona vía Sharp, pero estás sirviendo imágenes optimizadas desde tu origen único. Pon Cloudflare o un CDN delante.
  • Sin despliegues atómicos — Necesitas manejar despliegues sin tiempo de inactividad tú mismo (Docker Compose con health checks, o un proxy inverso como Caddy/Traefik).

Para la mayoría de aplicaciones en Social Animal, especialmente las compilaciones headless CMS que hacemos a través de nuestro trabajo de desarrollo headless CMS, un único VPS con un CDN delante es perfectamente adecuado.

Comparación de costos: Vercel vs Auto-Hosting

Hablemos de dinero. Esto se basa en datos de facturación real de una aplicación Next.js haciendo ~5M solicitudes/mes con ISR, optimización de imágenes, y renderización moderada del lado del servidor.

Factor de Costo Vercel Pro Vercel Enterprise AWS/SST Cloudflare Hetzner VPS
Plataforma base $20/usuario/mes Personalizado (~$3k+/mes) $0 $5/mes €7.49/mes
Cómputo/solicitudes $150-400/mes Incluido $40-80/mes $0-15/mes Incluido
Ancho de banda (100GB) Incluido Incluido $8.50 (CloudFront) Incluido Incluido
Optimización de imágenes $50-200/mes Incluido $5-15/mes (Lambda) $5/mes (CF Images) Incluido (Sharp)
ISR/Caché Incluido Incluido $2-5/mes (DynamoDB) $0-5/mes (KV) $0
Total Estimado $300-700/mes $3,000+/mes $55-110/mes $10-25/mes $8-15/mes

Esos números de Vercel no son hipotéticos. He visto las facturas. El precio por asiento, los sobrecargos de ejecución de funciones, y los cargos de ancho de banda en el nivel Pro se suman rápidamente para equipos de 5+.

Los números de AWS/SST asumen tráfico moderado con concurrencia provisionada. El precio de Cloudflare es genuinamente salvaje — es difícil gastar dinero real allí a menos que estés haciendo algo exótico.

Cuándo abandonar Vercel

No abandones solo porque puedas. Abandona porque deberías. Aquí está mi marco:

Quédate en Vercel si:

  • Tu equipo es pequeño (1-3 desarrolladores) y el tiempo del desarrollador es tu recurso más caro
  • Estás gastando menos de $100/mes en Vercel
  • No tienes a nadie a quien le guste el trabajo de infraestructura
  • Estás iterando rápido y necesitas previsualizaciones instantáneas para cada PR
  • Estás usando características específicas de Vercel como Analytics, Speed Insights, o integraciones del Vercel AI SDK

Abandona Vercel si:

  • La factura mensual supera $500 y está creciendo
  • Necesitas infraestructura en regiones específicas para cumplimiento (GDPR, residencia de datos)
  • Ya estás ejecutando infraestructura significativa de AWS/GCP/Cloudflare
  • Los cold starts en serverless son inaceptables para tu caso de uso
  • Necesitas estrategias de almacenamiento en caché personalizadas que no se ajusten al modelo de Vercel
  • Has alcanzado los límites de tamaño de función o tiempo de ejecución de Vercel

Considera seriamente abandonar si:

  • Estás en precios de Vercel Enterprise y la renovación del contrato acaba de llegar
  • Tu aplicación es principalmente estática/ISR y estás pagando precios SSR dinámicos
  • Quieres ejecutar tu frontend junto a tu backend en la misma infraestructura

La estrategia de migración

He hecho esto tres veces ahora. Aquí está el proceso que sigo, refinado a través de experiencia dolorosa.

Paso 1: Audita tus características de Next.js

Antes de tocar nada, cataloga qué características de Next.js realmente usas:

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

# Encuentra rutas API
find ./app -name "route.ts" -o -name "route.js" | head -20

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

# Busca acciones de servidor
grep -r "use server" ./app --include="*.ts" --include="*.tsx" | head -20

# Verifica next.config para características especiales
cat next.config.js

Paso 2: Elige tu objetivo

Basado en la auditoría:

  • ISR pesado + middleware + optimización de imágenes → AWS/SST
  • SSR simple + sitio de contenido → Cloudflare o VPS
  • Ya tienes infraestructura Docker/K8s → VPS/Docker
  • Necesita hacerse el viernes → Docker en Railway o Fly.io

Si estás construyendo con Next.js o Astro, la opción de plataforma de destino impacta significativamente en tus decisiones de arquitectura.

Paso 3: Configura CI/CD

El CI/CD de Vercel es genuinamente excelente. Lo extrañarás. Réplicalo con 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'

Paso 4: Despliegues de vista previa

Esta es la única cosa que la gente más extraña de Vercel. Para SST, usa etapas:

# En tu flujo de trabajo de CI de PR
npx sst deploy --stage pr-${{ github.event.pull_request.number }}

Para Docker, herramientas como Coolify (auto-alojado) o Railway manejan bien los despliegues de vista previa.

Paso 5: Transición de DNS

El momento real de la migración. Siempre recomiendo:

  1. Desplegar en nueva infraestructura junto a Vercel
  2. Probar exhaustivamente con un dominio de staging
  3. Bajar TTL de DNS a 60 segundos un día antes
  4. Cortar DNS durante horas de bajo tráfico
  5. Mantener despliegue de Vercel ejecutándose 48 horas como fallback
  6. Monitorear de cerca tasas de error, TTFB, y Core Web Vitals

Paso 6: Desmonta Vercel

Una vez que estés confiado (dale al menos una semana), cancela la suscripción de Vercel y elimina el proyecto. No dejes proyectos zombie acumulando cargos.

Errores comunes y cómo evitarlos

Variables de entorno desaparecidas. Next.js tiene variables con prefijo NEXT_PUBLIC_ (agrupadas en tiempo de compilación) y variables solo del servidor (disponibles en tiempo de ejecución). En Vercel, esta distinción es algo borrosa. En auto-hosting, es estricta. Asegúrate de que todas las variables NEXT_PUBLIC_ estén disponibles en tiempo de compilación en tu CI.

Caché ISR no persiste. En Docker, el directorio .next/cache necesita estar en un volumen persistente. De lo contrario, cada reinicio de contenedor pierde tus páginas en caché:

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

volumes:
  next-cache:

Fallos de instalación de Sharp. La biblioteca de optimización de imágenes sharp necesita binarios específicos de plataforma. En Docker, asegúrate de estar instalando dependencias dentro de la misma arquitectura que tu tiempo de ejecución. El Dockerfile anterior maneja esto usando compilaciones multi-etapa con la misma imagen base.

Diferencias de comportamiento de middleware. Vercel ejecuta middleware en su red edge. En AWS/SST, se ejecuta como una CloudFront Function (limitada a 10ms de ejecución, tamaño de 2MB). El middleware complejo puede necesitar ser movido a la función de servidor. He tenido que refactorizar middleware de autenticación por estos límites.

Encabezados y reescrituras faltantes. Si confiabas en vercel.json para encabezados, redirecciones o reescrituras, necesitas mover estos a next.config.js o tu configuración de CDN/proxy inverso.

Si algo de esto se siente abrumador, eso es exactamente el tipo de trabajo de infraestructura que manejamos en Social Animal. Consulta nuestro precio o contáctanos — hemos hecho estas migraciones suficientemente veces para tener un proceso refinado.

FAQ

¿Es OpenNext listo para producción en 2025?

Sí. OpenNext v3.x está ejecutando cargas de trabajo de producción para miles de empresas. El camino SST/AWS es el más probado en batalla, con soporte de Cloudflare de cerca atrás. No llamaría maduro aún al soporte de Google Cloud o Kubernetes desnudo, pero AWS y Cloudflare son sólidos.

¿OpenNext soporta Next.js App Router y Server Components?

Soporte completo. App Router, Server Components, Server Actions, streaming, y Suspense todos funcionan. El equipo de OpenNext sigue de cerca los lanzamientos de Next.js, aunque típicamente hay un retraso de 1-3 semanas después de versiones principales de Next.js antes de que OpenNext se ponga al día.

¿Cuánto puedo realmente ahorrar abandonando Vercel?

Depende fuertemente de tus patrones de uso. Para un equipo de 5 desarrolladores ejecutando una aplicación de tráfico moderado, he visto equipos pasar de $600-800/mes en Vercel Pro a $30-80/mes en AWS/SST o menos de $20/mes en un VPS. Los ahorros son reales pero también lo es la carga de mantenimiento adicional.

¿Puedo usar ISR (Incremental Static Regeneration) sin Vercel?

Absolutamente. En AWS/SST, ISR usa DynamoDB para el caché de etiquetas y SQS para revalidación asincrónica — está completamente funcional incluyendo revalidación bajo demanda vía revalidateTag() y revalidatePath(). En un VPS, ISR funciona con el caché del sistema de archivos, que está bien para despliegues de servidor único.

¿Qué hay de los despliegues de vista previa de Vercel? ¿Puedo replicar eso?

Puedes obtener el 80% de la experiencia. SST soporta despliegues basados en etapas, así que cada PR puede obtener su propio stack. Coolify y herramientas similares ofrecen despliegues de vista previa para configuraciones basadas en Docker. Lo que no fácilmente replicarás es el sistema de comentarios visual de Vercel y la integración estrecha con GitHub para estado de despliegue. La mayoría de los equipos encuentran el compromiso aceptable.

¿Debo usar OpenNext con Cloudflare o AWS para un sitio headless CMS?

Para sitios headless CMS ricos en contenido (Sanity, Contentful, Storyblok), Cloudflare Workers es una excelente opción. Estos sitios tienden a ser ISR-pesados con lógica del servidor relativamente ligera — perfecto para el modelo de precios de Cloudflare. Solo iría a AWS si necesitas características que Cloudflare aún no soporta o si estás profundamente en el ecosistema de AWS.

¿Es auto-alojar Next.js más difícil que auto-alojar Astro o Remix?

Honestamente, sí. Next.js tiene la salida de compilación más compleja de cualquier framework por características como ISR, middleware, optimización de imágenes, y pre-renderización parcial. Astro y Remix tienen historias de despliegue mucho más simples. Si estás iniciando un nuevo proyecto y el auto-hosting es una prioridad, considera Astro — es dramáticamente más simple de alojar. Pero si ya estás en Next.js, OpenNext hace la migración práctica.

¿Qué sucede si OpenNext deja de ser mantenido?

OpenNext está respaldado por SST y tiene una comunidad activa con patrocinadores principales. Dicho esto, esto es una preocupación legítima para cualquier dependencia de código abierto. La mitigación es que el enfoque Docker/standalone (next start) funciona sin OpenNext en absoluto — solo pierdes algunas de las características más avanzadas como revalidación de etiquetas ISR y middleware edge. Es una degradación elegante, no un acantilado.