# syntax=docker/dockerfile:1 # ── build: Astro static site + offline artifact + CSP hashes ────────────── FROM node:22-alpine@sha256:16e22a550f3863206a3f701448c45f7912c6896a62de43add43bb9c86130c3e2 AS build WORKDIR /app RUN corepack enable COPY package.json pnpm-lock.yaml ./ RUN --mount=type=cache,target=/root/.local/share/pnpm/store \ pnpm install --frozen-lockfile COPY . . ENV ASTRO_TELEMETRY_DISABLED=1 RUN pnpm build \ && find dist -type f \( -name '*.html' -o -name '*.css' -o -name '*.js' \ -o -name '*.svg' -o -name '*.xml' -o -name '*.txt' -o -name '*.webmanifest' \) \ -exec gzip -9k {} \; # ── serve: nginx, ~10MB, security headers, precompressed assets ─────────── FROM nginx:1.29-alpine@sha256:5616878291a2eed594aee8db4dade5878cf7edcb475e59193904b198d9b830de COPY docker/nginx.conf /etc/nginx/conf.d/default.conf COPY docker/security-headers.conf /etc/nginx/snippets/security-headers.conf # csp.conf is generated by scripts/gen-csp.mjs during `pnpm build` COPY --from=build /app/docker/csp.conf /etc/nginx/snippets/csp.conf COPY --from=build /app/dist /usr/share/nginx/html EXPOSE 80