# syntax=docker/dockerfile:1.7
#
# Production image for MEGA INFRASTRUCTURE — designed for Coolify.
#
# Multi-stage build:
#   1. deps    — fetch and cache npm dependencies
#   2. builder — compile the Next.js standalone bundle (postinstall
#                automatically patches Next 16's dev-only cross-site
#                guard so we can host under any domain / IP)
#   3. runner  — minimal runtime image with just the standalone server
#
# The container listens on ${PORT:-3000} and binds to 0.0.0.0 so
# Coolify's Traefik proxy can reach it. The /api/health endpoint is
# used as the container healthcheck.

# ---------------------------------------------------------------------------
# 1. deps
# ---------------------------------------------------------------------------
FROM node:20-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app

# Copy only the lockfile + manifest so this layer is cached as long
# as dependencies don't change.
COPY package.json package-lock.json* ./
# --ignore-scripts: the `postinstall` hook runs `scripts/patch-next-dev-blocker.cjs`
# which targets Next 16's dev-only cross-site guard. That module is never
# loaded in production, so the patch is unnecessary here. Skipping the
# hook also decouples the install from the rest of the workspace — the
# `scripts/` directory isn't copied until the next stage, but the hook
# would otherwise fail with `MODULE_NOT_FOUND`.
RUN npm ci --ignore-scripts --no-audit --no-fund

# ---------------------------------------------------------------------------
# 2. builder
# ---------------------------------------------------------------------------
FROM node:20-alpine AS builder
WORKDIR /app

# Pull in the prebuilt node_modules from the deps stage.
COPY --from=deps /app/node_modules ./node_modules

# Copy the rest of the source. Order matters: changing source code
# invalidates this layer, but the layer above (node_modules) is kept.
COPY . .

# Opt out of Next.js telemetry during the build.
ENV NEXT_TELEMETRY_DISABLED=1
ENV NODE_ENV=production

# Build the standalone server. This produces `.next/standalone/` which
# already contains the trimmed `node_modules` needed at runtime plus a
# ready-to-run `server.js`.
RUN npm run build

# ---------------------------------------------------------------------------
# 3. runner
# ---------------------------------------------------------------------------
FROM node:20-alpine AS runner
WORKDIR /app

ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV PORT=3000
ENV HOSTNAME=0.0.0.0

# Create a non-root user to run the app.
RUN addgroup --system --gid 1001 nodejs \
 && adduser --system --uid 1001 nextjs

# Static assets served directly by Next.js — must be copied alongside
# the standalone output.
COPY --from=builder /app/public ./public

# The standalone output already includes a trimmed node_modules and the
# Node executable wrapper. Static chunks live in `.next/static` and are
# loaded by the standalone server at runtime — they must be copied in
# separately because `output: "standalone"` does NOT bundle them.
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs
EXPOSE 3000

# Coolify / Traefik can hit /api/health for a 200 OK liveness probe.
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
  CMD wget -q --spider http://127.0.0.1:3000/api/health || exit 1

CMD ["node", "server.js"]
