# syntax=docker/dockerfile:1.7 ARG NODE_IMAGE=node:24.18.0-bookworm-slim # ============================================================ # 1. Instalación de dependencias # ============================================================ FROM ${NODE_IMAGE} AS deps WORKDIR /app ENV NEXT_TELEMETRY_DISABLED=1 \ NPM_CONFIG_AUDIT=false \ NPM_CONFIG_FUND=false \ NPM_CONFIG_FETCH_RETRIES=3 \ NPM_CONFIG_FETCH_RETRY_MINTIMEOUT=10000 \ NPM_CONFIG_FETCH_RETRY_MAXTIMEOUT=60000 \ NPM_CONFIG_FETCH_TIMEOUT=120000 \ NPM_CONFIG_MAXSOCKETS=6 \ NPM_CONFIG_LOGLEVEL=info COPY package.json package-lock.json ./ # Muestra las versiones y valida acceso al registro antes de instalar. RUN node --version \ && npm --version \ && npm config set registry https://registry.npmjs.org/ \ && npm config get registry \ && npm ping # sharing=private evita quedar esperando el caché de otro build. # timeout impide que npm quede bloqueado indefinidamente. RUN --mount=type=cache,target=/root/.npm,sharing=private \ timeout 600s npm ci \ --no-audit \ --no-fund \ --prefer-offline \ --loglevel=info \ --timing # ============================================================ # 2. Compilación de Next.js # ============================================================ FROM ${NODE_IMAGE} AS builder WORKDIR /app ENV NODE_ENV=production \ NEXT_TELEMETRY_DISABLED=1 \ NODE_OPTIONS=--max-old-space-size=2048 COPY --from=deps /app/node_modules ./node_modules COPY . . # Conserva el caché de compilación de Next.js entre builds. RUN --mount=type=cache,target=/app/.next/cache,sharing=private \ npm run build # Verifica que next.config.ts tenga output: "standalone". RUN test -f /app/.next/standalone/server.js # ============================================================ # 3. Imagen final de producción # ============================================================ FROM ${NODE_IMAGE} AS runner WORKDIR /app ENV NODE_ENV=production \ NEXT_TELEMETRY_DISABLED=1 \ HOSTNAME=0.0.0.0 \ PORT=80 # libcap permite que el usuario no-root escuche en el puerto 80. RUN apt-get update \ && apt-get install -y --no-install-recommends \ ca-certificates \ libcap2-bin \ && rm -rf /var/lib/apt/lists/* \ && groupadd --gid 1001 nodejs \ && useradd \ --uid 1001 \ --gid 1001 \ --create-home \ --shell /usr/sbin/nologin \ nextjs \ && setcap 'cap_net_bind_service=+ep' /usr/local/bin/node COPY --from=builder \ --chown=nextjs:nodejs \ /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 80 HEALTHCHECK \ --interval=30s \ --timeout=8s \ --start-period=30s \ --retries=3 \ CMD ["node", "-e", "fetch('http://127.0.0.1/api/health').then(r => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))"] CMD ["node", "server.js"]