Files
bztmon-site/Dockerfile
jwright dc42d31595 docker: digest-pin the node:22-bookworm-slim build base
Pin the floating node:22-bookworm-slim tag to its index digest. The re-resolve
of this unpinned docker.io tag every build was the recurring CI 'hang'. Paired
with the bastion runner now pulling through the zot mirror, the base is fetched
once and cached. (nginx runtime stage was already digest-pinned.)
2026-06-23 20:47:02 +10:00

32 lines
1.4 KiB
Docker

# syntax=docker/dockerfile:1
# Multi-stage: Debian build (Node; Chromium deps for Mermaid land in M3) →
# pinned nginx-unprivileged runtime serving the static dist/.
# ---- build stage ----------------------------------------------------------
# Digest-pinned (was a floating tag → the docker.io re-resolve was the CI "build hang"). With the bastion
# runner pointed at the zot pull-through mirror, this exact layer is fetched once and cached. Bump the digest
# when intentionally moving Node. node:22-bookworm-slim index digest resolved 2026-06-23.
FROM node:22-bookworm-slim@sha256:d9f850096136edbc402debdd8729579a288aac64574ada0ff4db26b6ae58b0b2 AS build
WORKDIR /app
# Install deps from the lockfile only first (better layer caching).
COPY package.json package-lock.json ./
RUN npm ci
# Build the static site.
COPY . .
RUN npm run build
# ---- runtime stage --------------------------------------------------------
# Same vetted digest used by the k8s Deployment. Renovate keeps it current.
FROM ghcr.io/nginx/nginx-unprivileged:1.28.0-alpine@sha256:c97ff0bf7cbae369953c6da1232ec14ad9f971d66360c5698db0856a4cd657a0
# Custom server config (security headers, caching, routing) + shared headers include.
COPY nginx/default.conf /etc/nginx/conf.d/default.conf
COPY nginx/security-headers.conf /etc/nginx/security-headers.conf
# The built site.
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 8080