# node:24-alpine, pinned to the index digest the tag pointed at when this lab was written.
# Renovate or Dependabot moves the pin forward through a reviewed pull request.
FROM node:24-alpine@sha256:ebfe2f90462722a7a4de65e91990e97fe0d401c70e0e762c5b53302f905ec1c1 AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev

FROM node:24-alpine@sha256:ebfe2f90462722a7a4de65e91990e97fe0d401c70e0e762c5b53302f905ec1c1
# The app never runs a package manager. Remove npm, npx, corepack and yarn so they are
# not shipped, scanned and patched with every release (the base layer still holds the bytes).
RUN rm -rf /usr/local/lib/node_modules /opt/yarn-v* \
      /usr/local/bin/npm /usr/local/bin/npx /usr/local/bin/corepack /usr/local/bin/yarn /usr/local/bin/yarnpkg
WORKDIR /app
ENV NODE_ENV=production PORT=3000
COPY --from=deps /app/node_modules ./node_modules
COPY package.json server.js healthcheck.js ./
# UID/GID 1000 is the image's "node" user. A numeric USER lets Kubernetes
# runAsNonRoot verify it without reading /etc/passwd.
USER 1000:1000
EXPOSE 3000
HEALTHCHECK --interval=10s --timeout=3s --start-period=5s --retries=3 \
  CMD ["node", "healthcheck.js"]
CMD ["node", "server.js"]
