Saltar al contenido

Next.js ​

Qué detecta Zenavo ​

Un repositorio con next en package.json se compila con zbpack como Node.js, framework next.js:

PasoComando
Instalarnpm install, pnpm install, yarn install o bun install, según el archivo de bloqueo del repositorio (yarn si no hay ninguno)
Compilarel script build, normalmente next build
Arrancarel script start, normalmente next start

La versión de Node.js sale de engines.node en package.json (22 si no está definida). Haz commit de tu archivo de bloqueo para que la instalación sea reproducible y se use el gestor de paquetes correcto.

next start escucha en $PORT, que Zenavo pone en 8080, en todas las interfaces, así que una aplicación por defecto no necesita cambios:

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

Desplegar ​

  1. Add Service → GitHub, elige el repositorio y la rama.
  2. Añade las variables que necesite la aplicación (ver abajo) y haz clic en Next.
  3. Comprueba que la vista previa muestra nodejs y next.js y haz clic en Deploy.
  4. En la pestaña Networking, genera un dominio o asocia el tuyo.

Variables de entorno ​

  • Las variables del lado del servidor (process.env.DATABASE_URL en route handlers, server components, getServerSideProps) se leen cuando la aplicación se ejecuta: defínelas en la pestaña Variable y vuelve a desplegar.
  • Las variables NEXT_PUBLIC_* las escribe next build en el bundle de JavaScript, así que deben existir durante la compilación. Las variables de la pestaña Variable solo llegan a la aplicación en ejecución, así que define estas en Settings → Build → Build arguments, por ejemplo NEXT_PUBLIC_API_URL=https://api.example.com, o NEXT_PUBLIC_API_URL=${API_URL} para reutilizar una variable. Llegan a la compilación sin Dockerfile; consulta argumentos de compilación.
  • La dirección del propio sitio es ZENAVO_<PORT>_URL, por ejemplo ${ZENAVO_WEB_URL}, cuando el puerto tiene un dominio. Úsala para NEXTAUTH_URL o similares.

Conecta una base de datos ​

Añade PostgreSQL al proyecto y referencia su variable desde el servicio de Next.js:

sh
DATABASE_URL=${POSTGRESQL_CONNECTION_STRING}

Prisma, Drizzle y pg aceptan esta URL. Ejecuta las migraciones cuando arranque el servicio, porque la compilación no llega a la base de datos: un script predeploy se ejecuta antes de start.

json
"scripts": {
  "build": "next build",
  "predeploy": "prisma migrate deploy",
  "start": "next start"
}

Imágenes más pequeñas con output: 'standalone' ​

Con output: 'standalone' en next.config.js, next build escribe un servidor autónomo en .next/standalone. zbpack no lo usa, así que para aprovecharlo añade un Dockerfile:

dockerfile
FROM node:22-alpine AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
ARG NEXT_PUBLIC_API_URL
RUN npm run build

FROM node:22-alpine
WORKDIR /app
ENV NODE_ENV=production HOSTNAME=0.0.0.0
COPY --from=build /app/.next/standalone ./
COPY --from=build /app/.next/static ./.next/static
COPY --from=build /app/public ./public
EXPOSE 3000
CMD ["node", "server.js"]

HOSTNAME=0.0.0.0 hace que el servidor standalone escuche en todas las interfaces, y el puerto sale de EXPOSE (aquí 3000). Cada variable que necesite la compilación, como NEXT_PUBLIC_API_URL, lleva una línea ARG antes de RUN npm run build y un valor en Settings → Build → Build arguments.

Problemas habituales ​

SíntomaCausa
La compilación falla con JavaScript heap out of memoryLas aplicaciones grandes necesitan más memoria de la que recibe una compilación por defecto. Añade NODE_OPTIONS=--max-old-space-size=4096 en Settings → Build → Build arguments (con tu propio Dockerfile, también ARG NODE_OPTIONS en la etapa de compilación), o aligera la compilación.
Un valor NEXT_PUBLIC_* es undefined en el navegadorSolo existe en la pestaña Variable. Defínelo como argumento de compilación y vuelve a desplegar. Con tu propio Dockerfile, declara también un ARG antes de next build.
Fallan las imágenes de next/imageLas imágenes remotas necesitan images.remotePatterns en next.config.js.
El servidor standalone es inalcanzableHOSTNAME no es 0.0.0.0, así que solo escucha en el nombre de host del contenedor.

Sin relación con Zeabur.