# syntax=docker/dockerfile:1
###############################################################################
# SHARP-ER web - React Router 8 (framework mode, SSR) on Node 22
#
# Adapted from the React Router template Dockerfile. Two things changed:
#   * npm -> pnpm, because this repository is a pnpm workspace and there is no
#     package-lock.json to `npm ci` from;
#   * the build context is the REPOSITORY ROOT, where pnpm-lock.yaml,
#     pnpm-workspace.yaml and .npmrc live.
#
#   docker build -f apps/web/Dockerfile -t sharper-web .
#   docker compose build web          # does exactly that
#
# The server reads STRAPI_URL / STRAPI_TOKEN / SITE_URL at RUN time, never at
# build time, so one image is valid for every environment.
###############################################################################

# --- base: the toolchain both stages share ----------------------------------
FROM node:22-bookworm-slim AS base
ENV PNPM_VERSION=9.12.3
RUN apt-get update \
 && apt-get install -y --no-install-recommends ca-certificates \
 && rm -rf /var/lib/apt/lists/* \
 && npm install --global "pnpm@${PNPM_VERSION}"
WORKDIR /repo


# --- build: install dependencies and produce build/client + build/server -----
FROM base AS build

# Manifests first so the install layer stays cached. Both workspace manifests
# are copied: pnpm checks the lockfile against every project in the workspace
# and treats it as stale if one is missing.
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
COPY apps/web/package.json ./apps/web/
COPY apps/cms/package.json ./apps/cms/

# `--filter web...` keeps Strapi out of this image entirely.
# devDependencies are required: vite, @react-router/dev and tailwind build here.
RUN pnpm install --frozen-lockfile --filter web...

COPY apps/web ./apps/web
RUN pnpm --filter web build


# --- runtime ----------------------------------------------------------------
FROM base AS runtime

ENV NODE_ENV=production \
    PORT=3000

COPY --from=build /repo/node_modules ./node_modules
COPY --from=build /repo/package.json /repo/pnpm-workspace.yaml /repo/.npmrc ./
COPY --from=build /repo/apps/web ./apps/web

RUN chown -R node:node /repo/apps/web
USER node
WORKDIR /repo/apps/web
EXPOSE 3000

# /en is a real page: it proves the SSR handler renders, not just that a socket
# is open. It stays 200 even when the CMS is unreachable, because every route
# falls back to its bundled draft copy - so this healthcheck tracks the web
# service alone.
HEALTHCHECK --interval=15s --timeout=5s --start-period=30s --retries=5 \
  CMD node -e "fetch('http://127.0.0.1:'+(process.env.PORT||3000)+'/en').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"

# react-router-serve, the production server that ships with the framework.
CMD ["pnpm", "start"]
