# Keep in sync with ui/.nvmrc.
FROM node:24.18.1-alpine@sha256:f70403e87646dc51b45295f4b8b70cdad0b63d2297c4c9899119b03f7af7a6b3 AS base

LABEL maintainer="https://github.com/prowler-cloud"

# The build uses pnpm via corepack, so npm is unused — remove it (and npx) to drop
# the bundled-npm CVE surface from every stage, incl. prod.
# No blanket apk upgrade: it resolves against Alpine's live repo, so the digest pin
# above would not make the image reproducible. Move the digest forward instead, or
# take a named package as the targeted exception below.
RUN corepack enable && rm -rf /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx

# High CVEs fixed in Alpine 3.24 but not yet in the pinned base image:
#   libcrypto3/libssl3 3.5.8-r0  CVE-2026-14456, CVE-2026-14457, CVE-2026-18798,
#                                CVE-2026-54874, CVE-2026-63072, CVE-2026-63075,
#                                CVE-2026-63076  (image ships 3.5.7-r0)
# The base image pins node 24.18.1, which has not been rebuilt since that package
# was published, so the upgrade is taken here rather than by moving the pin -- the
# newest published node:24-alpine (24.19.0, built 2026-08-03) predates the
# 2026-08-13 advisory and carries the same vulnerable version. libcrypto3 and
# libssl3 are both built from openssl and are flagged separately, so both are named.
# `>=` rather than `=`: Alpine keeps only the newest build of a package in a
# branch's index, so an exact pin breaks this build the day 3.5.8-r0 is superseded.
# Drop this once the base image ships 3.5.8-r0 or later.
RUN apk add --no-cache --upgrade \
    "libcrypto3>=3.5.8-r0" \
    "libssl3>=3.5.8-r0"

# Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
#hadolint ignore=DL3018
RUN apk add --no-cache libc6-compat
WORKDIR /app

# Install dependencies based on the preferred package manager
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY scripts ./scripts
ENV NODE_OPTIONS=--max-old-space-size=4096
RUN corepack install && pnpm install --frozen-lockfile


# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Install pinned pnpm so build uses the exact version from package.json.
# Alternative: move COPY package.json + corepack install to base stage to avoid
# re-downloading, at the cost of invalidating all stages on any package.json change.
RUN corepack install

# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry during the build.
ENV NEXT_TELEMETRY_DISABLED=1
ARG NEXT_PUBLIC_PROWLER_RELEASE_VERSION
ENV NEXT_PUBLIC_PROWLER_RELEASE_VERSION=${NEXT_PUBLIC_PROWLER_RELEASE_VERSION}

# GTM / API base+docs URLs are runtime container env (prod stage), not build ARGs.

RUN pnpm run build

# Development stage
FROM base AS dev
WORKDIR /app

# Set up environment for development
ENV NODE_ENV=development
ENV NEXT_TELEMETRY_DISABLED=1
COPY --from=builder /app /app

# Run development server with hot-reloading
CMD ["pnpm", "run", "dev"]

# Production stage
FROM base AS prod
WORKDIR /app

# Set up environment for production
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1

RUN addgroup --system --gid 1001 nodejs &&\
adduser --system --uid 1001 nextjs

COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
COPY --from=builder --chown=nextjs:nodejs /app/public ./public

USER nextjs

EXPOSE 3000

ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
# Runtime configuration is read by `node server.js` at container start and is
# NOT baked into the image. Supply it via your orchestrator (docker-compose,
# Helm/K8s):
#   - required: UI_API_BASE_URL, AUTH_URL, AUTH_SECRET (missing ⇒ fail fast at boot)
#   - optional: UI_API_DOCS_URL
#   - optional: UI_CLOUD_ENABLED ("true" only in Prowler Cloud deployments)
#   - gated integrations (load only when *_ENABLED="true"; the value is then
#     required or boot fails). Their legacy names (NEXT_PUBLIC_SENTRY_*,
#     NEXT_PUBLIC_GOOGLE_TAG_MANAGER_ID, POSTHOG_KEY/HOST) still work:
#       UI_SENTRY_ENABLED + UI_SENTRY_DSN (+ optional UI_SENTRY_ENVIRONMENT)
#       UI_GOOGLE_TAG_MANAGER_ENABLED + UI_GOOGLE_TAG_MANAGER_ID
#       UI_POSTHOG_ENABLED + UI_POSTHOG_KEY + UI_POSTHOG_HOST (feedback survey)
#   - reserved: REO_DEV_CLIENT_ID (no consumer yet)
# server.js is created by next build from the standalone output
# https://nextjs.org/docs/pages/api-reference/next-config-js/output
CMD ["node", "server.js"]
