# Build on a workstation/CI for small production hosts. Override bases with
# tested image@sha256:... references for reproducible releases.
ARG NODE_IMAGE=node:22-bookworm-slim
ARG PYTHON_IMAGE=python:3.13-alpine
FROM ${PYTHON_IMAGE} AS source
WORKDIR /src
COPY . .
# Build from the explicit public-source manifest, then extract only that
# reviewed tree. Unlisted content never reaches the runtime or source download.
RUN python scripts/build-source-release.py && \
    python -c "import zipfile; zipfile.ZipFile('content/releases/trading-dev-academy-source.zip').extractall('/export')" && \
    mkdir -p /export/trading-dev-academy/content/releases && \
    cp content/releases/trading-dev-academy-source.zip* /export/trading-dev-academy/content/releases/

FROM ${NODE_IMAGE} AS dependencies
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev --ignore-scripts && npm cache clean --force

FROM ${NODE_IMAGE} AS runtime
WORKDIR /app
ENV NODE_ENV=production HOST=0.0.0.0 PORT=8000 PAPER_WORKER=0
COPY --from=dependencies /app/node_modules ./node_modules
COPY --from=dependencies /app/package*.json ./
COPY --from=source /export/trading-dev-academy/index.html /export/trading-dev-academy/favicon.svg /export/trading-dev-academy/LICENSE /export/trading-dev-academy/CONTRIBUTING.md /export/trading-dev-academy/THIRD_PARTY_NOTICES.md ./
COPY --from=source /export/trading-dev-academy/css ./css
COPY --from=source /export/trading-dev-academy/js ./js
COPY --from=source /export/trading-dev-academy/vendor ./vendor
COPY --from=source --chown=node:node /export/trading-dev-academy/content ./content
COPY --from=source /export/trading-dev-academy/scripts/*.js ./scripts/
RUN mkdir -p /app/.state && chown node:node /app/.state
USER node
EXPOSE 8000
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
    CMD node -e "fetch('http://127.0.0.1:8000/healthz',{signal:AbortSignal.timeout(3000)}).then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"
CMD ["node", "--max-old-space-size=192", "scripts/serve.js"]
