# syntax=docker/dockerfile:1 # Author: cirakg & claude ai # Summary: garmin-otp/docs image: Markdown lint and Mermaid rendering for `make docs`. # # garmin-otp/docs: documentation checks for `make docs`. # * markdownlint-cli2 lints every Markdown file. # * mermaid-cli renders every Mermaid diagram to SVG (build/docs/), which # proves the diagrams parse; it drives a headless Chrome through Puppeteer. # # Reproducibility: the Node base image is pinned by digest, Debian packages come # from a dated snapshot, npm packages install from package-lock.json (resolved # from releases published before the cutoff date in the Makefile), and the # headless Chrome build is the one pinned by that Puppeteer version. ARG NODE_IMAGE=node@sha256:c3de60bf2f9dd0ac6370e6117950ff62d6e339527e7472301c9c78a017978392 FROM ${NODE_IMAGE} # Dated snapshot of the Debian archive (https://snapshot.debian.org). ARG DEBIAN_SNAPSHOT=20261001T000000Z LABEL project=garmin-otp \ org.opencontainers.image.title="garmin-otp/docs" \ org.opencontainers.image.description="Markdown lint and Mermaid rendering for the project docs" ENV DEBIAN_FRONTEND=noninteractive \ LANG=C.UTF-8 \ LC_ALL=C.UTF-8 # CA certificates first, so apt can use the HTTPS snapshot mirror. They come # from the image's default (signed) Debian sources. RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates \ && rm -rf /var/lib/apt/lists/* # Shared libraries headless Chrome needs, plus fonts for diagram labels. # Snapshot Release files carry expired Valid-Until dates by design, so that # check is switched off; signatures are still verified. RUN rm -f /etc/apt/sources.list.d/debian.sources \ && printf '%s\n' \ "deb https://snapshot.debian.org/archive/debian/${DEBIAN_SNAPSHOT} bookworm main" \ "deb https://snapshot.debian.org/archive/debian/${DEBIAN_SNAPSHOT} bookworm-updates main" \ "deb https://snapshot.debian.org/archive/debian-security/${DEBIAN_SNAPSHOT} bookworm-security main" \ > /etc/apt/sources.list \ && echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf.d/99snapshot \ && apt-get update \ && apt-get install -y --no-install-recommends \ libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 libdbus-1-3 \ libxkbcommon0 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 libxshmfence1 \ libgbm1 libasound2 libpango-1.0-0 libcairo2 libx11-xcb1 libexpat1 \ fonts-dejavu-core fonts-liberation \ unzip \ && rm -rf /var/lib/apt/lists/* # npm packages from the lock file. Install scripts are disabled; the one # download a script would do (Puppeteer's browser) is done explicitly instead, # so it lands in a known folder inside the image. WORKDIR /opt/docs-tools ENV PUPPETEER_CACHE_DIR=/opt/docs-tools/puppeteer-cache COPY docs/package.json docs/package-lock.json docs/puppeteer.json ./ RUN npm ci --ignore-scripts --no-audit --no-fund \ && npx --no-install puppeteer browsers install chrome-headless-shell \ && chmod -R a+rX /opt/docs-tools ENV PATH=/opt/docs-tools/node_modules/.bin:${PATH} \ HOME=/tmp WORKDIR /work