# Base matches the approved Approval Engine Alpine family; scan each candidate. # Built by owner CI (.forgejo/workflows/service-image.yaml) from a tarball of the pushed commit; the # wheel is built inside the image from source, so no workstation dist/ is involved. FROM python:3.12-alpine@sha256:b64631e04e4920160c50fbe8d8df828f7f35f06f425cb44aa09bca53e708a35a AS wheel ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 PIP_DISABLE_PIP_VERSION_CHECK=1 COPY requirements-build.lock /src/requirements-build.lock RUN pip install --no-cache-dir --require-hashes --only-binary=:all: -r /src/requirements-build.lock COPY pyproject.toml /src/pyproject.toml COPY informed_decision /src/informed_decision RUN pip wheel --no-cache-dir --no-deps --no-build-isolation --wheel-dir /dist /src FROM python:3.12-alpine@sha256:b64631e04e4920160c50fbe8d8df828f7f35f06f425cb44aa09bca53e708a35a AS build ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 PATH=/opt/venv/bin:$PATH RUN python -m venv /opt/venv COPY requirements.lock /build/requirements.lock RUN pip install --no-cache-dir --require-hashes --only-binary=:all: -r /build/requirements.lock COPY --from=wheel /dist/ /build/ RUN pip install --no-cache-dir --no-deps --no-index /build/informed_decision-*.whl FROM python:3.12-alpine@sha256:b64631e04e4920160c50fbe8d8df828f7f35f06f425cb44aa09bca53e708a35a ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 PATH=/opt/venv/bin:$PATH # zlib >= 1.3.2-r1 (INFD-WP-0009-T05 remediation, live since 2026-10-11 in f5588f49): the same # hash-pinned, Alpine-signed package the zlib overlay installs, upgraded offline. The build fails # if the result is older; a newer zlib already in the base is left as is. COPY deploy/zlib-overlay/zlib-1.3.2-r1.apk deploy/zlib-overlay/APKINDEX.tar.gz /tmp/infd-zlib/x86_64/ RUN echo '63aeea03c15a2f9018f81805cfc8aa926bdf5cd68921f22149c2fbb5d0ee9f47 /tmp/infd-zlib/x86_64/zlib-1.3.2-r1.apk' | sha256sum -c - \ && echo '24fc2ccb08f3125429a38b31bd6c76a7b394c6236df0975760dc8259e50dfbd5 /tmp/infd-zlib/x86_64/APKINDEX.tar.gz' | sha256sum -c - \ && apk verify /tmp/infd-zlib/x86_64/zlib-1.3.2-r1.apk /tmp/infd-zlib/x86_64/APKINDEX.tar.gz \ && apk upgrade --no-logfile --no-network --no-cache --no-preupgrade --repositories-file /dev/null --repository /tmp/infd-zlib zlib \ && apk info --exists 'zlib>=1.3.2-r1' \ && rm -rf /tmp/infd-zlib RUN apk add --no-cache 'libuuid>=2.42.3-r1' \ && apk info --exists 'zlib>=1.3.2-r1' \ && addgroup -S -g 10001 informed \ && adduser -S -u 10001 -G informed -H informed COPY --from=build /opt/venv /opt/venv # No package installer or build tooling belongs in the running service. RUN rm -rf /usr/local/bin/pip* /usr/local/lib/python3.12/site-packages/pip* \ /usr/local/lib/python3.12/site-packages/setuptools* /usr/local/lib/python3.12/site-packages/pkg_resources \ /opt/venv/bin/pip* /opt/venv/lib/python3.12/site-packages/pip* \ /opt/venv/lib/python3.12/site-packages/setuptools* /opt/venv/lib/python3.12/site-packages/pkg_resources WORKDIR /app USER 10001:10001 EXPOSE 8080 8081 ENTRYPOINT ["informed-decision-container"]