Despliegue

Felicitaciones, es hora de llevar su aplicación a producción.

Puede desplegar Next.js gestionado con Vercel o autoalojarlo en un servidor Node.js, una imagen Docker o incluso como archivos HTML estáticos. Al desplegar usando next start, todas las características de Next.js son compatibles.

Construcciones de Producción

Ejecutar next build genera una versión optimizada de su aplicación para producción. Se crean archivos HTML, CSS y JavaScript basados en sus páginas. El JavaScript se compila y los paquetes del navegador se minifican usando el Compilador de Next.js para ayudar a lograr el mejor rendimiento y compatibilidad con todos los navegadores modernos.

Next.js produce una salida de despliegue estándar utilizada por Next.js gestionado y autoalojado. Esto garantiza que todas las características sean compatibles en ambos métodos de despliegue. En la próxima versión principal, transformaremos esta salida en nuestra especificación de la API de Salida de Construcción.

Next.js gestionado con Vercel

Vercel, los creadores y mantenedores de Next.js, proporcionan infraestructura gestionada y una plataforma de experiencia de desarrollador para sus aplicaciones Next.js.

Desplegar en Vercel no requiere configuración y proporciona mejoras adicionales para escalabilidad, disponibilidad y rendimiento global. Sin embargo, todas las características de Next.js siguen siendo compatibles cuando se autoalojan.

Aprenda más sobre Next.js en Vercel o despliegue una plantilla gratis para probarlo.

Autoalojamiento

Puede autoalojar Next.js de tres maneras diferentes:

Servidor Node.js

Next.js puede desplegarse en cualquier proveedor de alojamiento que soporte Node.js. Asegúrese de que su package.json tenga los scripts "build" y "start":

package.json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start"
  }
}

Luego, ejecute npm run build para construir su aplicación. Finalmente, ejecute npm run start para iniciar el servidor Node.js. Este servidor soporta todas las características de Next.js.

Imagen Docker

Next.js puede desplegarse en cualquier proveedor de alojamiento que soporte contenedores Docker. Puede usar este enfoque al desplegar en orquestadores de contenedores como Kubernetes o al ejecutar dentro de un contenedor en cualquier proveedor de nube.

  1. Instale Docker en su máquina
  2. Clone nuestro ejemplo (o el ejemplo multi-entorno)
  3. Construya su contenedor: docker build -t nextjs-docker .
  4. Ejecute su contenedor: docker run -p 3000:3000 nextjs-docker

Next.js a través de Docker soporta todas las características de Next.js.

Exportación Estática HTML

Next.js permite comenzar como un sitio estático o una Aplicación de Página Única (SPA), y luego actualizar opcionalmente para usar características que requieran un servidor.

Dado que Next.js soporta esta exportación estática, puede desplegarse y alojarse en cualquier servidor web que pueda servir activos estáticos HTML/CSS/JS. Esto incluye herramientas como AWS S3, Nginx o Apache.

Ejecutarse como una exportación estática no soporta características de Next.js que requieran un servidor. Aprenda más.

Nota importante:

Características

Optimización de Imágenes

Optimización de Imágenes a través de next/image funciona autoalojado sin configuración al desplegar usando next start. Si prefiere tener un servicio separado para optimizar imágenes, puede configurar un cargador de imágenes.

La optimización de imágenes puede usarse con una exportación estática definiendo un cargador de imágenes personalizado en next.config.js. Tenga en cuenta que las imágenes se optimizan en tiempo de ejecución, no durante la construcción.

Nota importante:

Middleware

Middleware funciona autoalojado sin configuración al desplegar usando next start. Dado que requiere acceso a la solicitud entrante, no es compatible cuando se usa una exportación estática.

Middleware usa un tiempo de ejecución que es un subconjunto de todas las API disponibles de Node.js para ayudar a garantizar baja latencia, ya que puede ejecutarse frente a cada ruta o activo en su aplicación. Este tiempo de ejecución no requiere ejecutarse "en el borde" y funciona en un servidor de una sola región. Se requiere configuración e infraestructura adicionales para ejecutar Middleware en múltiples regiones.

Si busca agregar lógica (o usar un paquete externo) que requiera todas las API de Node.js, podría mover esta lógica a un layout como un Componente del Servidor. Por ejemplo, verificando encabezados y redireccionando. También puede usar encabezados, cookies o parámetros de consulta para redireccionar o reescribir a través de next.config.js. Si eso no funciona, también puede usar un servidor personalizado.

Variables de Entorno

Next.js puede soportar variables de entorno tanto en tiempo de construcción como en tiempo de ejecución.

Por defecto, las variables de entorno solo están disponibles en el servidor. Para exponer una variable de entorno al navegador, debe tener el prefijo NEXT_PUBLIC_. Sin embargo, estas variables de entorno públicas se incluirán en el paquete JavaScript durante next build.

Para leer variables de entorno en tiempo de ejecución, recomendamos usar getServerSideProps o adoptar incrementalmente el Enrutador de Aplicaciones. Con el Enrutador de Aplicaciones, podemos leer variables de entorno en el servidor de forma segura durante el renderizado dinámico. Esto le permite usar una única imagen Docker que puede promoverse a través de múltiples entornos con diferentes valores.

import { unstable_noStore as noStore } from 'next/cache';

export default function Component() {
  noStore();
  // cookies(), headers() y otras funciones dinámicas
  // también optarán por el renderizado dinámico, haciendo
  // que esta variable de entorno se evalúe en tiempo de ejecución
  const value = process.env.MY_VALUE
  ...
}

Nota importante:

Caché e ISR

Next.js puede almacenar en caché respuestas, páginas estáticas generadas, salidas de construcción y otros activos estáticos como imágenes, fuentes y scripts.

El almacenamiento en caché y la revalidación de páginas (usando Regeneración Estática Incremental (ISR) o funciones más nuevas en el Enrutador de Aplicaciones) usan la misma caché compartida. Por defecto, esta caché se almacena en el sistema de archivos (en disco) en su servidor Next.js. Esto funciona automáticamente al autoalojar usando tanto el Enrutador de Páginas como el de Aplicaciones.

Puede configurar la ubicación de la caché de Next.js si desea persistir páginas y datos en caché en almacenamiento duradero, o compartir la caché entre múltiples contenedores o instancias de su aplicación Next.js.

Caché Automática

  • Next.js establece el encabezado Cache-Control de public, max-age=31536000, immutable para activos verdaderamente inmutables. No se puede anular. Estos archivos inmutables contienen un hash SHA en el nombre del archivo, por lo que pueden almacenarse en caché indefinidamente de forma segura. Por ejemplo, Importaciones de Imágenes Estáticas. Puede configurar el TTL para imágenes.
  • La Regeneración Estática Incremental (ISR) establece el encabezado Cache-Control de s-maxage: <revalidate in getStaticProps>, stale-while-revalidate. Este tiempo de revalidación se define en su función getStaticProps en segundos. Si establece revalidate: false, se establecerá por defecto una duración de caché de un año.
  • Las páginas renderizadas dinámicamente establecen un encabezado Cache-Control de private, no-cache, no-store, max-age=0, must-revalidate para evitar que los datos específicos del usuario se almacenen en caché. Esto aplica tanto al Enrutador de Aplicaciones como al de Páginas. Esto también incluye Modo Borrador.

Activos Estáticos

Si desea alojar activos estáticos en un dominio o CDN diferente, puede usar la configuración assetPrefix en next.config.js. Next.js usará este prefijo de activo al recuperar archivos JavaScript o CSS. Separar sus activos a un dominio diferente tiene la desventaja de tiempo adicional dedicado a resolución DNS y TLS.

Aprenda más sobre assetPrefix.

Configuración de Caché

Por defecto, los activos de caché generados se almacenarán en memoria (por defecto 50mb) y en disco. Si está alojando Next.js usando una plataforma de orquestación de contenedores como Kubernetes, cada pod tendrá una copia de la caché. Para evitar que se muestren datos obsoletos ya que la caché no se comparte entre pods por defecto, puede configurar la caché de Next.js para proporcionar un manejador de caché y desactivar el almacenamiento en caché en memoria.

Para configurar la ubicación de la Caché ISR/Data al autoalojar, puede configurar un manejador personalizado en su archivo next.config.js:

next.config.js
module.exports = {
  cacheHandler: require.resolve('./cache-handler.js'),
  cacheMaxMemorySize: 0, // desactivar almacenamiento en caché en memoria por defecto
}

Luego, cree cache-handler.js en la raíz de su proyecto, por ejemplo:

cache-handler.js
const cache = new Map()

module.exports = class CacheHandler {
  constructor(options) {
    this.options = options
  }

  async get(key) {
    // Esto podría almacenarse en cualquier lugar, como almacenamiento duradero
    return cache.get(key)
  }

  async set(key, data, ctx) {
    // Esto podría almacenarse en cualquier lugar, como almacenamiento duradero
    cache.set(key, {
      value: data,
      lastModified: Date.now(),
      tags: ctx.tags,
    })
  }

  async revalidateTag(tag) {
    // Iterar sobre todas las entradas en la caché
    for (let [key, value] of cache) {
      // Si las etiquetas del valor incluyen la etiqueta especificada, eliminar esta entrada
      if (value.tags.includes(tag)) {
        cache.delete(key)
      }
    }
  }
}

Usar un manejador de caché personalizado le permitirá garantizar consistencia entre todos los pods que alojan su aplicación Next.js. Por ejemplo, puede guardar los valores en caché en cualquier lugar, como Redis o AWS S3.

Nota importante:

  • revalidatePath es una capa de conveniencia sobre las etiquetas de caché. Llamar a revalidatePath llamará a la función revalidateTag con una etiqueta especial por defecto para la página proporcionada.

Caché de Construcción

Next.js genera un ID durante next build para identificar qué versión de su aplicación se está sirviendo. La misma construcción debe usarse e iniciarse en múltiples contenedores.

Si está reconstruyendo para cada etapa de su entorno, necesitará generar un ID de construcción consistente para usar entre contenedores. Use el comando generateBuildId en next.config.js:

next.config.js
module.exports = {
  generateBuildId: async () => {
    // Esto podría ser cualquier cosa, usando el último hash de git
    return process.env.GIT_HASH
  },
}

Desfase de Versión

Next.js mitigará automáticamente la mayoría de las instancias de desfase de versión y recargará automáticamente la aplicación para recuperar nuevos activos cuando se detecte. Por ejemplo, si hay una discrepancia en el deploymentId, las transiciones entre páginas realizarán una navegación dura versus usar un valor precargado.

Cuando la aplicación se recarga, puede haber una pérdida del estado de la aplicación si no está diseñada para persistir entre navegaciones de página. Por ejemplo, usar estado en la URL o almacenamiento local persistiría el estado después de una recarga de página. Sin embargo, el estado del componente como useState se perdería en tales navegaciones.

Vercel proporciona protección adicional contra desfases para aplicaciones Next.js para garantizar que los activos y funciones de la versión anterior sigan estando disponibles para clientes antiguos, incluso después de desplegar la nueva versión.

Puede configurar manualmente la propiedad deploymentId en su archivo next.config.js para garantizar que cada solicitud use ya sea la cadena de consulta ?dpl o el encabezado x-deployment-id.

Apagado manual controlado (Graceful Shutdown)

Cuando se aloja la aplicación por cuenta propia (self-hosting), es posible que desee ejecutar código cuando el servidor se apague debido a señales SIGTERM o SIGINT.

Puede configurar la variable de entorno NEXT_MANUAL_SIG_HANDLE como true y luego registrar un manejador para esa señal dentro de su archivo _document.js. Deberá registrar la variable de entorno directamente en el script del package.json, no en el archivo .env.

Nota importante: El manejo manual de señales no está disponible en next dev.

package.json
{
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "NEXT_MANUAL_SIG_HANDLE=true next start"
  }
}
pages/_document.js
if (process.env.NEXT_MANUAL_SIG_HANDLE) {
  process.on('SIGTERM', () => {
    console.log('Received SIGTERM: cleaning up')
    process.exit(0)
  })
  process.on('SIGINT', () => {
    console.log('Received SIGINT: cleaning up')
    process.exit(0)
  })
}