# syntax=docker/dockerfile:1 # # BentoPDF for bau-pm: BentoPDF built from source at a pinned commit with # BentoPDF's own air-gapped build options, every module it would otherwise load # from a CDN served from this image, and bau-pm's hand-off glue added to every # page. Nothing here edits BentoPDF's code: its documented build arguments, its # runtime config.json, its generated header file with the hosts taken out, and # our files beside its own. # # The images are upstream's: the builder and the runtime stage are the ones # BentoPDF's Dockerfile uses. ARG BENTOPDF_REF=v2.8.8 ARG BENTOPDF_COMMIT=f96cd4e5166f3d51393dfe9f3c440b5bb77802f1 ARG NODE_IMAGE=public.ecr.aws/docker/library/node:20-alpine ARG NGINX_IMAGE=quay.io/nginx/nginx-unprivileged:alpine-slim # --- BentoPDF's source, at the commit the tag must point to --- FROM ${NODE_IMAGE} AS source ARG BENTOPDF_REF ARG BENTOPDF_COMMIT RUN apk add --no-cache git RUN git clone --quiet --depth 1 --branch "${BENTOPDF_REF}" https://github.com/alam00000/bentopdf.git /src \ && actual=$(git -C /src rev-parse HEAD) \ && if [ "$actual" != "${BENTOPDF_COMMIT}" ]; then \ echo "BentoPDF ${BENTOPDF_REF} is ${actual}, expected ${BENTOPDF_COMMIT}" >&2; exit 1; \ fi \ && rm -rf /src/.git # --- The CDN modules, packed from npm and checked against vendor.lock --- FROM ${NODE_IMAGE} AS vendor COPY --from=source /src/bentopdf-airgap-bundle /src/bentopdf-airgap-bundle COPY vendor.lock /vendor.lock COPY --chmod=755 scripts/vendor.sh /usr/local/bin/vendor.sh RUN vendor.sh /src /vendor.lock /wasm # --- BentoPDF's build, as BentoPDF's Dockerfile runs it --- FROM ${NODE_IMAGE} AS builder WORKDIR /app COPY --from=source /src/package.json /src/package-lock.json ./ COPY --from=source /src/vendor ./vendor ENV HUSKY=0 RUN npm config set fetch-retries 5 \ && npm config set fetch-retry-mintimeout 60000 \ && npm config set fetch-retry-maxtimeout 300000 \ && npm config set fetch-timeout 600000 \ && npm ci COPY --from=source /src ./ # The air-gapped build: every module path is this image's own, the CORS proxy # (used only by the X.509 tool, which config.json disables) is switched off, # and Simple Mode drops the marketing pages. Relative paths, so the image does # not know the hostname it will be served under. ENV SIMPLE_MODE=true \ DISABLE_GITHUB_STARS=true \ COMPRESSION_MODE=all \ BASE_URL= \ VITE_DEFAULT_LANGUAGE=de \ VITE_CORS_PROXY_URL= \ VITE_WASM_PYMUPDF_URL=/wasm/pymupdf/ \ VITE_WASM_GS_URL=/wasm/gs/ \ VITE_WASM_CPDF_URL=/wasm/cpdf/ \ VITE_TESSERACT_WORKER_URL=/wasm/ocr/worker.min.js \ VITE_TESSERACT_CORE_URL=/wasm/ocr/core \ VITE_TESSERACT_LANG_URL=/wasm/ocr/lang-data \ VITE_TESSERACT_AVAILABLE_LANGUAGES=deu,fra,ita,eng \ VITE_OCR_FONT_BASE_URL=/wasm/ocr/fonts \ VITE_EMBEDPDF_FONTS_URL=/wasm/embedpdf \ NODE_OPTIONS=--max-old-space-size=3072 RUN npm run build COPY --chmod=755 scripts/finish.sh /usr/local/bin/finish.sh RUN finish.sh /app # --- Upstream's runtime stage, with our files beside BentoPDF's --- FROM ${NGINX_IMAGE} ARG BENTOPDF_REF ARG SOURCE_URL=https://src.bundespruefstelle.ch/magdev/bau-pm-pdf-tools ARG VERSION=dev LABEL org.opencontainers.image.title="bau-pm-pdf-tools" \ org.opencontainers.image.description="BentoPDF ${BENTOPDF_REF} for bau-pm, without third-party hosts" \ org.opencontainers.image.source="${SOURCE_URL}" \ org.opencontainers.image.version="${VERSION}" \ org.opencontainers.image.licenses="AGPL-3.0-only" ENV DISABLE_IPV6=false \ PORT=8080 USER root RUN apk upgrade --no-cache USER nginx COPY --chown=nginx:nginx --from=builder /app/dist /usr/share/nginx/html COPY --chown=nginx:nginx --from=builder /app/nginx.conf /etc/nginx/nginx.conf COPY --chown=nginx:nginx --from=builder /app/security-headers.conf /etc/nginx/security-headers.conf COPY --chown=nginx:nginx --from=builder /app/security-headers-docs.conf /etc/nginx/security-headers-docs.conf COPY --chown=nginx:nginx --chmod=755 --from=builder /app/nginx-ipv6.sh /docker-entrypoint.d/99-disable-ipv6.sh COPY --chown=nginx:nginx --chmod=755 --from=builder /app/nginx-noindex.sh /docker-entrypoint.d/98-noindex.sh COPY --chown=nginx:nginx --from=vendor /wasm /usr/share/nginx/html/wasm COPY --chown=nginx:nginx config/config.json /usr/share/nginx/html/config.json COPY --chown=nginx:nginx glue/ /usr/share/nginx/html/bau-pm/ RUN sed -i "s#__BAU_PM_SOURCE_URL__#${SOURCE_URL}/src/tag/${VERSION}#" /usr/share/nginx/html/bau-pm/handoff.js \ && grep -q "${SOURCE_URL}" /usr/share/nginx/html/bau-pm/handoff.js \ && mkdir -p /etc/nginx/tmp EXPOSE 8080 HEALTHCHECK --interval=30s --timeout=5s --retries=3 CMD wget --spider -q http://127.0.0.1:8080/ || exit 1 CMD ["nginx", "-g", "daemon off;"]