Next.js
Qué detecta Zenavo
Un repositorio con next en package.json se compila con zbpack como Node.js, framework next.js:
| Paso | Comando |
|---|---|
| Instalar | npm install, pnpm install, yarn install o bun install, según el archivo de bloqueo del repositorio (yarn si no hay ninguno) |
| Compilar | el script build, normalmente next build |
| Arrancar | el 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:
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
}
}Desplegar
- Add Service → GitHub, elige el repositorio y la rama.
- Añade las variables que necesite la aplicación (ver abajo) y haz clic en Next.
- Comprueba que la vista previa muestra nodejs y next.js y haz clic en Deploy.
- En la pestaña Networking, genera un dominio o asocia el tuyo.
Variables de entorno
- Las variables del lado del servidor (
process.env.DATABASE_URLen 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 escribenext builden 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 ejemploNEXT_PUBLIC_API_URL=https://api.example.com, oNEXT_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 paraNEXTAUTH_URLo similares.
Conecta una base de datos
Añade PostgreSQL al proyecto y referencia su variable desde el servicio de Next.js:
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.
"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:
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íntoma | Causa |
|---|---|
La compilación falla con JavaScript heap out of memory | Las 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 navegador | Solo 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/image | Las imágenes remotas necesitan images.remotePatterns en next.config.js. |
| El servidor standalone es inalcanzable | HOSTNAME no es 0.0.0.0, así que solo escucha en el nombre de host del contenedor. |