# syntax=docker/dockerfile:1 ARG PYTHON_BASE_IMAGE=python:3.12-slim@sha256:2f17fc044b579bab302c2e8054d3a686e2cb9a83de48e70534b94cd8ebbe06a9 # Both bases are pinned by digest; override with the repository variables to # move them forward deliberately. # nginx 1.31.6. The 1.28 line pins nginx=1.28.3-r1 in /etc/apk/world, so its five # HIGH findings cannot be upgraded in place; 1.29 scans worse. This one is clean. ARG NGINX_BASE_IMAGE=nginx:alpine@sha256:62ff2089abf5a9ed33bd232895bef5e22f7bb4b200675cec49a5ebc48e3d4ac8 FROM ${PYTHON_BASE_IMAGE} AS policy WORKDIR /build COPY web /build/web COPY infra /build/infra COPY deploy /build/deploy ENV NGINX_TEMPLATE=/build/deploy/nginx.conf.template RUN python infra/compile_web.py FROM ${NGINX_BASE_IMAGE} # Same reason as the API image: a pinned base freezes its packages. RUN apk upgrade --no-cache ARG VCS_REF=unknown LABEL org.opencontainers.image.title="DTF Site and Kanban" \ org.opencontainers.image.revision="$VCS_REF" \ org.opencontainers.image.source="DTF System repository" ENV WEB_INDEX=index.html PUBLIC_HOST=invalid.example S3_PUBLIC_ENDPOINT=https://invalid.example COPY --from=policy /build/default.conf.template /etc/nginx/templates/default.conf.template # The HTML from the policy stage, with every asset address versioned. COPY --from=policy /build/web/ /usr/share/nginx/html/ # The official entrypoint renders the server configuration at startup and Nginx # writes its PID/cache files. Keep the service non-root while granting it # ownership of only those runtime locations. This works in Docker Swarm, # where the previous read-only/tmpfs combination was not mounted as expected. RUN chown -R 101:101 /etc/nginx/conf.d /var/cache/nginx /run USER 101:101 EXPOSE 8080