File size: 10,001 Bytes
bff1348
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fc30527
df7146b
 
 
fc30527
df7146b
 
 
 
 
fc30527
df7146b
fc30527
df7146b
 
 
 
 
 
 
 
fc30527
df7146b
 
 
 
fc30527
df7146b
fc30527
 
bff1348
 
 
657a5ae
 
 
 
 
 
 
 
 
 
bff1348
df7146b
 
 
bff1348
 
df7146b
bff1348
 
4223748
 
 
 
 
 
df7146b
 
 
 
 
 
 
 
4223748
 
df7146b
 
bff1348
 
4223748
 
 
657a5ae
 
 
bff1348
 
 
fc30527
 
df7146b
 
 
fc30527
bff1348
 
 
cecde1f
bff1348
 
 
 
 
657a5ae
 
 
7d5b986
5c32d96
7d5b986
5c32d96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
657a5ae
 
 
5c32d96
 
 
 
 
 
 
 
657a5ae
 
 
 
 
 
 
 
 
 
 
 
 
 
bff1348
 
 
 
 
 
 
 
 
 
 
 
 
e224609
bff1348
 
 
 
 
 
 
 
a25f0d4
bff1348
 
 
a25f0d4
bff1348
 
a25f0d4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# 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.
#
# Sprint S6.1 โ€” reproductibilitรฉ institutionnelle (BnF) :
#
# ``tesseract-ocr`` n'est PAS pinnรฉ ร  une version exacte (ex :
# ``=5.3.0-2``) car Debian point-release rebump frรฉquemment :
# ``5.3.0-2`` โ†’ ``5.3.0-2+deb12u1`` โ†’ ``5.3.4-1``.  Un pin exact
# casse le build dรจs que la version disparaรฎt du miroir.
#
# Le contrat de reproductibilitรฉ repose plutรดt sur :
#
# 1. La base image Python pinรฉe par digest SHA256 (cf. ``ARG
#    PYTHON_BASE_IMAGE`` ci-dessus) โ€” Debian bookworm garantit la
#    stabilitรฉ ABI au sein du mรชme point-release.
# 2. ``requirements-docker.lock`` qui fige les versions Python.
# 3. Le ``RunManifest.dependencies_lock`` capture la version
#    Tesseract effective au runtime (``tesseract --version``)
#    pour traรงabilitรฉ scientifique.
#
# Si une version mineure de Tesseract introduit une rรฉgression
# CER, le mainteneur peut pinner explicitement ICI ร  ce moment-lร 
# (avec une note CHANGELOG).
RUN apt-get update && \
    apt-get upgrade -y && \
    apt-get install -y --no-install-recommends \
        # Tesseract OCR 5 + modรจles de langues (Debian bookworm).
        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"]