# Production image for Content Factory.
#
# The shape follows the upstream packaged image: one container holds the three
# applications, nginx listens on 5000, serves the frontend from 4200 and proxies
# /api to the backend on 3000. The orchestrator has no public surface and talks
# to Temporal directly.
#
# The build stage exists so the compiler toolchain and the pnpm content store —
# together larger than the application itself — never reach the shipped image.

FROM node:22.23.2-bookworm-slim AS build

ARG NEXT_PUBLIC_VERSION
ENV NEXT_PUBLIC_VERSION=$NEXT_PUBLIC_VERSION

# `next build` reports anonymous usage to Vercel unless this is set. The
# `telemetry: false` in next.config.js belongs to the Sentry plugin and does
# nothing for Next itself, so the build was announcing "Next.js now collects
# completely anonymous telemetry" on every run.
ENV NEXT_TELEMETRY_DISABLED=1

RUN apt-get update && apt-get install -y --no-install-recommends \
    ca-certificates \
    g++ \
    make \
    python3 \
&& rm -rf /var/lib/apt/lists/*

RUN npm --no-update-notifier --no-fund --global install pnpm@10.6.1

WORKDIR /app
COPY . /app

RUN pnpm install --frozen-lockfile
# pnpm intentionally skips dependency install scripts. The operator's offline
# migrate diff needs Prisma's matching native schema engine in the final image.
RUN node node_modules/@prisma/engines/scripts/postinstall.js \
 && echo '431f23f13da76244d6cffe1b7a8d80f544e0812eed009492cf545f220d88a4b2  node_modules/@prisma/engines/schema-engine-debian-openssl-3.0.x' | sha256sum --check
RUN NODE_OPTIONS="--max-old-space-size=4096" pnpm run build


FROM node:22.23.2-bookworm-slim AS runtime

RUN apt-get update && apt-get install -y --no-install-recommends \
    ca-certificates \
    curl \
    nginx \
&& rm -rf /var/lib/apt/lists/*

RUN addgroup --system www \
 && adduser --system --ingroup www --home /www --shell /usr/sbin/nologin www \
 && mkdir -p /www /uploads \
 && chown -R www:www /www /var/lib/nginx

# Runtime starts native Node processes through PM2. Prisma's operator CLI is
# already installed in /app/node_modules; package managers are build tools.
# PM2 7.0.3 pins vulnerable js-yaml 4.3.0, so replace that one direct dependency
# with its compatible security patch. Keep PM2's process/CLI contract unchanged.
RUN npm --no-update-notifier --no-fund --global install pm2@7.0.3 \
 && npm --prefix /usr/local/lib/node_modules/pm2 --no-update-notifier --no-fund \
    install --omit=dev --ignore-scripts --no-package-lock --save-exact js-yaml@4.3.2 \
 && rm -rf /usr/local/lib/node_modules/npm /usr/local/lib/node_modules/corepack \
    /opt/yarn-v1.22.22 /root/.npm \
 && rm -f /usr/local/bin/npm /usr/local/bin/npx /usr/local/bin/corepack \
    /usr/local/bin/yarn /usr/local/bin/yarnpkg

WORKDIR /app
COPY --from=build /app /app

# The Corresponding Source this deployment owes every network user under
# AGPL-3.0 section 13, served by /api/public/source.
#
# It is produced outside the build, by scripts/release/make-source-archive.sh,
# and not here — `.dockerignore` keeps `.git` out of the build context, and the
# slim Node image has no git, so `git archive` cannot run in the build stage.
# That is also the safer arrangement: no stage of this image ever holds the
# commit history, which carries a personal e-mail address.
#
# Naming both files explicitly is the point. If the archive was not built, this
# COPY fails and the image is never produced, instead of shipping an
# application whose Source page has nothing to offer.
COPY var/source/content-factory-source.tar.gz var/source/source.json /app/var/source/

COPY var/docker/nginx.conf /etc/nginx/nginx.conf
COPY var/docker/entrypoint.sh /usr/local/bin/content-factory-entrypoint
RUN chmod +x /usr/local/bin/content-factory-entrypoint

ENV NODE_ENV=production
# `DO_NOT_TRACK` asks every library that understands it not to report usage.
# Set in the image so editing a file on the server cannot lose it. (The
# CopilotKit switch beside it left with the library, `kcxz.28`.)
ENV DO_NOT_TRACK=1
EXPOSE 5000

HEALTHCHECK --interval=30s --timeout=5s --start-period=180s --retries=5 \
  CMD sh /app/var/docker/healthcheck.sh

CMD ["/usr/local/bin/content-factory-entrypoint"]
