# node:26-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:26-alpine@sha256:40cd011b55415bc894e45b02fdd5a5dfde056921b7d23a64c74f80497af48797 AS deps
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev

FROM node:26-alpine@sha256:40cd011b55415bc894e45b02fdd5a5dfde056921b7d23a64c74f80497af48797
# 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"]
