Guía de despliegue

Desplegar una aplicación Next.js en un VPS

Desplegar en un VPS Cloud →

Tutorial

Desplegar una aplicación Next.js en un VPS

Desarrollo13 min de lectura6 pasos

Next.js combina renderizado del lado del servidor, generación estática y rutas API en un único framework React. Desplegarlo en un VPS en lugar de en una plataforma propietaria le libera de las cuotas de funciones, de los límites de ancho de banda y del vendor lock-in, manteniendo el SSR plenamente operativo.

Contenido· ¿Por qué autoalojar Next.js en un VPS?1/14
  1. 01¿Por qué autoalojar Next.js en un VPS?
  2. 02Beneficios concretos de un Next.js autoalojado
  3. 03Requisitos de hardware y software
  4. 04Build Docker multi-stage: node:20-alpine
  5. 05Variables de entorno: .env.local vs .env.production
  6. 06Desplegar Next.js paso a paso
  7. 07Configuración completa de Nginx con upstream
  8. 08Estrategia ISR: revalidación y persistencia de caché
  9. 09Server Components vs Client Components: impacto en RAM y CPU
  10. 10CI/CD: GitHub Actions o Forgejo
  11. 11Monitorización con PM2
  12. 12Resolución de errores comunes en producción
  13. 13Copia de seguridad de .next/cache
  14. 14Desplegar Next.js con un clic desde el Marketplace

¿Por qué autoalojar Next.js en un VPS?

Next.js suele asociarse a una plataforma de alojamiento concreta, pero su servidor Node.js standalone funciona perfectamente en cualquier VPS. El autoalojamiento resulta pertinente en cuanto usted utiliza de forma intensiva el SSR, la ISR (regeneración estática incremental) o las rutas API: estas funcionalidades consumen invocaciones facturadas en las plataformas gestionadas, mientras que son gratuitas e ilimitadas en su propio servidor. Usted controla la caché ISR en disco, el ancho de banda de las imágenes optimizadas y el tiempo de ejecución de las funciones, sin límite de 10 segundos.

Beneficios concretos de un Next.js autoalojado

  • SSR y rutas API sin cuota de invocaciones ni facturación por función.
  • Caché ISR persistente en disco, sin revalidaciones perdidas entre despliegues.
  • Ancho de banda incluido, ideal para sitios con muchas imágenes y vídeos.
  • Varios proyectos Next.js en un mismo VPS, agrupados bajo Nginx.
  • Optimización de imágenes next/image servida localmente sin coste adicional por transformación.
  • Compilación y despliegue bajo control mediante Git, CI/CD o un simple git pull y recompilación.

Requisitos de hardware y software

La compilación de Next.js consume mucha memoria: prevea al menos 2 GB de RAM (4 GB para un proyecto grande con muchas páginas), ya que de lo contrario la compilación puede fallar por falta de memoria. Del lado del runtime, 1 o 2 vCPU bastan para servir el SSR. Instale Node.js 18 o 20 LTS, ya sea de forma nativa con nvm o mediante una imagen Docker node:20-alpine. Active output: 'standalone' en next.config.js para un despliegue ligero.

Build Docker multi-stage: node:20-alpine

Un build Docker multi-stage reduce la imagen final a lo esencial y evita incluir las herramientas de compilación en producción. La estrategia de tres etapas — deps, builder, runner — es la más habitual para Next.js en modo standalone.

# Etapa 1 — dependencias
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev

# Etapa 2 — compilación
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

# Etapa 3 — runner (imagen final)
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
EXPOSE 3000
CMD ["node", "server.js"]

La etapa deps instala únicamente las dependencias de producción (--omit=dev). La etapa builder copia el código fuente completo y ejecuta npm run build. La etapa runner contiene solo la carpeta standalone generada por Next.js, los activos estáticos y la carpeta public.

Variables de entorno: .env.local vs .env.production

Next.js distingue dos familias de variables según su alcance.

Variables públicas (NEXT_PUBLIC_*): se incluyen en el bundle JavaScript en tiempo de compilación y quedan expuestas al navegador. Adecuadas para una URL de API pública, un ID de Google Analytics o un indicador de funcionalidad. Nunca coloque secretos en ellas.

Variables de servidor: se leen únicamente en el lado Node (rutas API, Server Components, getServerSideProps). Nunca se envían al cliente. Aquí viven las claves de API externas, las cadenas de conexión a la base de datos y los secretos JWT.

En el VPS, dos enfoques coexisten: inyectar las variables en el entorno del proceso PM2 mediante su archivo de ecosistema (ecosystem.config.js), o pasarlas a Docker con --env-file .env.production. El segundo es preferible: el archivo permanece en el disco del servidor, fuera del repositorio git.

Nota: las variables NEXT_PUBLIC_* deben conocerse en tiempo de compilación. Si cambia una variable pública tras el build, debe recompilar la aplicación.

Desplegar Next.js paso a paso

  1. Preparar el servidor

    Por SSH, instale Node.js 20 LTS y PM2 (npm install -g pm2), o Docker. Clone el repositorio y cree .env.production con sus variables (NEXT_PUBLIC_* para el cliente, secretos de servidor para las rutas API).

  2. Compilar la aplicación

    Ejecute npm ci y después npm run build. Con output: 'standalone', Next.js genera una carpeta .next/standalone autónoma que contiene únicamente las dependencias necesarias, lo que aligera notablemente la imagen.

  3. Iniciar el servidor Node

    Inicie el servidor con pm2 start node --name nextjs -- .next/standalone/server.js en el puerto 3000, o mediante un contenedor Docker. Configure pm2 startup y pm2 save para un reinicio automático al arrancar de nuevo el VPS.

  4. Configurar Nginx como frontal

    Cree un bloque de servidor que haga proxy_pass http://localhost:3000, transmita las cabeceras Host y X-Forwarded-For, y sirva directamente /_next/static/ desde el disco para aliviar a Node. Active la compresión gzip.

  5. Instalar el certificado SSL

    Obtenga un certificado Let's Encrypt mediante Certbot para votredomaine.com, fuerce la redirección HTTPS y configure la renovación automática. Compruebe que las cabeceras X-Forwarded-Proto se transmiten correctamente para el SSR.

  6. Implantar los despliegues

    Automatice el ciclo git pull && npm ci && npm run build && pm2 reload nextjs mediante un script o un webhook de Git. El reload de PM2 garantiza un reinicio sin corte de servicio (zero-downtime) entre dos versiones.

Configuración completa de Nginx con upstream

Un bloque Nginx completo para Next.js va más allá del proxy_pass mínimo. Es necesario servir los activos estáticos directamente desde el disco, gestionar las cabeceras de caché, activar la compresión y transmitir correctamente la información del cliente.

upstream nextjs_upstream {
  server 127.0.0.1:3000;
  keepalive 64;
}

server {
  listen 443 ssl http2;
  server_name yourdomain.com;

  gzip on;
  gzip_types text/plain text/css application/javascript application/json image/svg+xml;

  location /_next/static/ {
    alias /home/deploy/myapp/.next/static/;
    expires 1y;
    add_header Cache-Control "public, immutable";
  }

  location / {
    proxy_pass http://nextjs_upstream;
    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;
  }
}

El bloque upstream con keepalive 64 mantiene un grupo de conexiones persistentes hacia Node, evitando la negociación TCP en cada petición. La directiva proxy_http_version 1.1 es obligatoria para que las conexiones keepalive funcionen realmente.

Estrategia ISR: revalidación y persistencia de caché

La ISR (Incremental Static Regeneration) permite a Next.js regenerar una página estática en segundo plano tras un retardo dado, sin una recompilación completa. En un VPS, esto requiere que la caché sobreviva a los reinicios.

// app/productos/[id]/page.tsx (App Router)
export const revalidate = 3600; // regenerar cada hora

La caché ISR se almacena en .next/cache. Dos opciones para que sobreviva a los redespliegues:

Opción 1 — volumen persistente: monte .next/cache fuera de la carpeta de despliegue y restáurela tras cada rebuild.

Opción 2 — cache handler Redis: para varias instancias Node o necesidad de compartir entre máquinas, Next.js soporta cache handlers personalizados desde la versión 13.4.

Para sitios con poco tráfico, la opción 1 es suficiente. La opción 2 se vuelve necesaria con varios procesos Node (cluster PM2) o varios VPS detrás de un balanceador de carga.

Server Components vs Client Components: impacto en RAM y CPU

Desde Next.js 13 y el App Router, los componentes son Server Components por defecto. La distinción tiene consecuencias directas sobre el consumo de recursos de su VPS.

Server Components se ejecutan únicamente en el servidor. Pueden leer la base de datos directamente, acceder al sistema de archivos, y no se envían nunca al bundle JavaScript del navegador. El resultado es HTML puro, lo que reduce el tamaño del bundle del cliente y mejora los Core Web Vitals (LCP).

Client Components ('use client' al principio del archivo) se hidratan en el navegador. Son necesarios para las interacciones del usuario: eventos, estado local, hooks (useState, useEffect).

La regla práctica en un VPS: mantener los Server Components para todo lo que toca a los datos, y limitar los Client Components a las zonas de interacción.

CI/CD: GitHub Actions o Forgejo

Automatizar el despliegue evita errores humanos y garantiza que cada fusión en la rama principal desencadene una recompilación limpia. Dos soluciones habituales en VPS: GitHub Actions (si su repositorio está en GitHub) y Forgejo (forge autoalojada, alternativa de código abierto a GitHub/Gitea).

name: Deploy Next.js
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy via SSH
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.VPS_HOST }}
          username: deploy
          key: ${{ secrets.VPS_SSH_KEY }}
          script: |
            cd /home/deploy/myapp
            git pull origin main
            npm ci
            npm run build
            pm2 reload nextjs

En ambos casos, los secretos se configuran en los secretos del repositorio y no aparecen nunca en los registros.

Monitorización con PM2

PM2 es a la vez el gestor de procesos y la primera herramienta de monitorización de su aplicación Next.js. Comandos esenciales:

# Estado de los procesos
pm2 list

# Registros en tiempo real
pm2 logs nextjs

# Métricas de CPU y RAM
pm2 monit

# Reinicio sin corte de servicio
pm2 reload nextjs

Active pm2-logrotate para evitar que los archivos de registro llenen el disco:

pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 50M
pm2 set pm2-logrotate:retain 7

En producción, guarde la lista de procesos tras cada cambio: pm2 save.

Si utiliza la ISR, monte un volumen persistente para la carpeta .next/cache a fin de que las páginas revalidadas sobrevivan a los redespliegues. Sin ello, cada recompilación parte de una caché vacía y provoca un pico de generación sobre la marcha. Para varias instancias Node detrás de un balanceador de carga, externalice esa caché hacia un almacenamiento compartido o Redis con un cache handler personalizado.

Resolución de errores comunes en producción

Tres a cinco errores se repiten sistemáticamente en el primer despliegue de una aplicación Next.js en un VPS.

ENOMEM durante npm run build
Aumente el límite de memoria de Node:

NODE_OPTIONS="--max-old-space-size=4096" npm run build

Port 3000 already in use
Identifique y detenga el proceso que ocupa el puerto:

lsof -i :3000
kill -9 <PID>

MODULE_NOT_FOUND en producción con output: 'standalone'
Copie las tres carpetas necesarias:

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

Bucle de redirección HTTPS con X-Forwarded-Proto
Asegúrese de que Nginx reenvía X-Forwarded-Proto: https y de que su aplicación lee esta cabecera para determinar el protocolo real.

Copia de seguridad de .next/cache

La carpeta .next/cache contiene dos tipos de datos valiosos: las páginas ISR revalidadas y la caché de compilación de Webpack/SWC. Perder esta caché obliga a Next.js a regenerar todas las páginas ISR al primer acceso, lo que puede generar un pico de carga.

Establezca una copia de seguridad sencilla con rsync o tar antes de cada despliegue. La caché de Webpack acelera notablemente las recompilaciones posteriores — en un proyecto mediano, una recompilación con caché completa tarda entre un 40 y un 60 % menos que una compilación en frío.

Desplegar Next.js con un clic desde el Marketplace

El Marketplace de ServOrbit ofrece una plantilla Next.js Stack que configura automáticamente Node.js LTS, PM2, Nginx y PostgreSQL en su VPS. En unos minutos, su entorno de producción está listo para recibir su aplicación React SSR — sin configuración manual.

Frente a la instalación descrita en esta guía, la plantilla se encarga de la puesta en marcha inicial y le permite empezar directamente en el paso «desplegar su código».

Su entorno Next.js listo en unos minutos

La plantilla Next.js Stack configura automáticamente Node.js LTS, PM2, Nginx y PostgreSQL — lista para recibir su aplicación React SSR.

¿Necesita ayuda?

Consulte nuestro centro de ayuda y nuestra FAQ, o contacte con nuestro equipo: llamada, WhatsApp o correo electrónico. Soporte en francés, inglés y árabe.

Escribir por WhatsAppse abre en una pestaña nueva