Spaces:
Sleeping
Sleeping
Claude
feat(sprint-A16): build Docker reproductible (digest + lock file) β clΓ΄ture M-2
df7146b unverified | # Dockerfile β Picarones | |
| # Image Docker multi-Γ©tape avec Tesseract OCR prΓ©-installΓ© | |
| # | |
| # Usage : | |
| # docker build -t picarones:latest . | |
| # docker run -p 8000:8000 picarones:latest | |
| # docker run -p 8000:8000 -v $(pwd)/corpus:/app/corpus picarones:latest | |
| # | |
| # Variables d'environnement supportΓ©es : | |
| # OPENAI_API_KEY, ANTHROPIC_API_KEY, MISTRAL_API_KEY | |
| # GOOGLE_APPLICATION_CREDENTIALS | |
| # AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_DEFAULT_REGION | |
| # AZURE_DOC_INTEL_ENDPOINT, AZURE_DOC_INTEL_KEY | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Γtape 1 : builder β installe les dΓ©pendances Python dans un venv | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Sprint A8 (M-2) + Sprint A16 (build dΓ©terministe) β image de base | |
| # Γ©pinglΓ©e Γ la fois par tag (lisibilitΓ© humaine) et par digest sha256 | |
| # (reproductibilitΓ© bit-Γ -bit). | |
| # | |
| # Pourquoi le digest : ``python:3.11.13-slim`` peut Γͺtre re-publiΓ© au | |
| # fil des patches Debian avec un mΓͺme tag mais un contenu diffΓ©rent. | |
| # Pour la reproductibilitΓ© institutionnelle BnF, ``@sha256:...`` fige | |
| # l'image binaire β deux ``docker build`` sΓ©parΓ©s produisent une | |
| # couche de base identique octet par octet. | |
| # | |
| # Rotation trimestrielle (avant chaque release majeure) : | |
| # | |
| # TOKEN=$(curl -s "https://auth.docker.io/token?\ | |
| # service=registry.docker.io&scope=repository:library/python:pull" \ | |
| # | jq -r .token) | |
| # curl -sI -H "Authorization: Bearer $TOKEN" \ | |
| # -H "Accept: application/vnd.oci.image.index.v1+json" \ | |
| # https://registry-1.docker.io/v2/library/python/manifests/3.11.13-slim \ | |
| # | grep -i docker-content-digest | |
| # # β mettre Γ jour le digest ci-dessous + bumper PYTHON_BASE_IMAGE | |
| # | |
| # La forme ``image:tag@sha256:...`` est documentΓ©e par Docker comme | |
| # valide ; les machines de dΓ©veloppement sans registry proxy peuvent | |
| # pull aussi bien que par tag β le digest Γ©tant immuable, le pull | |
| # est strictement Γ©quivalent Γ un pull par tag actuel. | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| ARG PYTHON_BASE_IMAGE=python:3.11.13-slim@sha256:9bffe4353b925a1656688797ebc68f9c525e79b1d377a764d232182a519eeec4 | |
| FROM ${PYTHON_BASE_IMAGE} AS builder | |
| WORKDIR /app | |
| # Sprint A14 (correctif suite scan Trivy CI) β applique en prioritΓ© les | |
| # patches Debian disponibles AVANT d'installer build-essential/git, pour | |
| # Γ©viter d'embarquer les CVE de la base image (libssl3t64, libc6, etc.). | |
| RUN apt-get update && \ | |
| apt-get upgrade -y && \ | |
| apt-get install -y --no-install-recommends \ | |
| build-essential \ | |
| git && \ | |
| apt-get clean && \ | |
| rm -rf /var/lib/apt/lists/* | |
| # Copier les fichiers de configuration du package + lock file Docker. | |
| # ``requirements-docker.lock`` (Sprint A16) gèle l'arbre de dépendances | |
| # transitif rΓ©solu par ``uv pip compile pyproject.toml --extra web --extra llm``. | |
| COPY pyproject.toml . | |
| COPY README.md . | |
| COPY requirements-docker.lock . | |
| COPY picarones/ picarones/ | |
| # CrΓ©e le venv isolΓ© /opt/venv et l'active pour les ``RUN`` suivants. | |
| # Le runtime fera ``COPY --from=builder /opt/venv /opt/venv`` ; sans cette | |
| # crΓ©ation explicite le COPY Γ©choue (rΓ©gression remontΓ©e par CI A14). | |
| RUN python -m venv /opt/venv | |
| ENV PATH="/opt/venv/bin:$PATH" | |
| # Sprint A16 : installation dΓ©terministe via lock file. | |
| # | |
| # 1. Patch pip/setuptools/wheel (Trivy scanne /opt/venv/lib/python3.11/ | |
| # site-packages β sans patch les CVE setuptools/wheel ressortent). | |
| # 2. ``--no-deps`` sur le lock empΓͺche pip de re-rΓ©soudre β l'arbre | |
| # pinnΓ© par ``uv pip compile`` est complet, transitives incluses. | |
| # 3. ``--no-deps`` sur picarones lui-mΓͺme : le lock contient dΓ©jΓ | |
| # toutes ses dΓ©pendances ; cette ligne installe juste le code. | |
| RUN pip install --upgrade --no-cache-dir \ | |
| "pip>=24.2" "setuptools>=78.1.1" "wheel>=0.46.2" && \ | |
| pip install --no-cache-dir --no-deps -r requirements-docker.lock && \ | |
| pip install --no-cache-dir --no-deps -e . && \ | |
| pip cache purge | |
| # Patch également la copie système de pip/setuptools/wheel (hors venv) | |
| # que Trivy dΓ©tecte via ``/usr/local/lib/python3.11/site-packages`` β | |
| # subsiste dans l'image runtime mΓͺme quand le venv est utilisΓ©. | |
| RUN /usr/local/bin/pip install --upgrade --no-cache-dir \ | |
| "pip>=24.2" "setuptools>=78.1.1" "wheel>=0.46.2" | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Γtape 2 : runtime β image finale lΓ©gΓ¨re avec Tesseract | |
| # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # ARG redΓ©clarΓ© ici car les variables ARG hors ``FROM`` sont scopΓ©es | |
| # par Γ©tape ; sans cette redΓ©claration le ``FROM`` du runtime perd | |
| # l'Γ©pinglage du builder. La valeur DOIT correspondre Γ celle de | |
| # l'Γ©tape builder (digest inclus) β sinon les couches OS divergent. | |
| ARG PYTHON_BASE_IMAGE=python:3.11.13-slim@sha256:9bffe4353b925a1656688797ebc68f9c525e79b1d377a764d232182a519eeec4 | |
| FROM ${PYTHON_BASE_IMAGE} AS runtime | |
| LABEL description="Picarones β Plateforme de comparaison de moteurs OCR pour documents patrimoniaux" | |
| LABEL version="1.0.0" | |
| LABEL org.opencontainers.image.source="https://github.com/maribakulj/Picarones" | |
| LABEL org.opencontainers.image.licenses="Apache-2.0" | |
| WORKDIR /app | |
| # ββ DΓ©pendances systΓ¨me βββββββββββββββββββββββββββββββββββββββββ | |
| # Sprint A14 (correctif Trivy) : ``apt-get upgrade -y`` avant install | |
| # pour rΓ©cupΓ©rer les patches de sΓ©curitΓ© Debian (libssl3t64, libc6, | |
| # openssl, etc.) β la base image Python ne les inclut pas par dΓ©faut. | |
| RUN apt-get update && \ | |
| apt-get upgrade -y && \ | |
| apt-get install -y --no-install-recommends \ | |
| # Tesseract OCR 5 et modèles de langues | |
| tesseract-ocr \ | |
| tesseract-ocr-fra \ | |
| tesseract-ocr-lat \ | |
| tesseract-ocr-eng \ | |
| tesseract-ocr-deu \ | |
| tesseract-ocr-ita \ | |
| tesseract-ocr-spa \ | |
| # Bibliothèques image pour Pillow | |
| libpng16-16 \ | |
| libjpeg62-turbo \ | |
| libtiff6 \ | |
| libwebp7 \ | |
| # Utilitaires | |
| curl && \ | |
| apt-get clean && \ | |
| rm -rf /var/lib/apt/lists/* | |
| # Patch pip/setuptools/wheel système du runtime (en dehors du venv). | |
| # Trivy scanne /usr/local/lib/python3.11/site-packages indΓ©pendamment. | |
| RUN /usr/local/bin/pip install --upgrade --no-cache-dir \ | |
| "pip>=24.2" "setuptools>=78.1.1" "wheel>=0.46.2" | |
| # ββ Venv Python depuis le builder ββββββββββββββββββββββββββββββ | |
| COPY --from=builder /opt/venv /opt/venv | |
| ENV PATH="/opt/venv/bin:$PATH" | |
| # ββ Code source de l'application βββββββββββββββββββββββββββββββ | |
| COPY --from=builder /app /app | |
| # ββ RΓ©pertoires de donnΓ©es ββββββββββββββββββββββββββββββββββββββ | |
| RUN mkdir -p /app/corpus /app/rapports /app/data | |
| # ββ Utilisateur non-root pour la sΓ©curitΓ© ββββββββββββββββββββββ | |
| RUN useradd -m -u 1000 picarones && \ | |
| chown -R picarones:picarones /app /opt/venv | |
| USER picarones | |
| # ββ Variables d'environnement par dΓ©faut βββββββββββββββββββββββ | |
| ENV PYTHONUNBUFFERED=1 | |
| ENV PYTHONIOENCODING=utf-8 | |
| ENV TESSDATA_PREFIX=/usr/share/tesseract-ocr/5/tessdata | |
| # ββ Ports βββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| EXPOSE 7860 | |
| # ββ Health check ββββββββββββββββββββββββββββββββββββββββββββββββ | |
| HEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3 \ | |
| CMD curl -f http://localhost:7860/health || exit 1 | |
| # ββ DΓ©marrage βββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| CMD ["picarones", "serve", "--host", "0.0.0.0", "--port", "7860"] | |