File size: 3,347 Bytes
e0fd571
a8c3223
35a94af
ed312af
 
e0fd571
ed312af
eec7490
 
 
 
 
 
 
 
 
 
 
 
 
 
ed312af
 
 
 
 
 
 
 
 
 
 
a8c3223
ed312af
 
a8c3223
 
 
 
 
eec7490
ed312af
 
 
 
eec7490
 
 
ed312af
 
 
a8c3223
 
 
ed312af
b986b08
 
 
 
ed312af
 
a43daf6
 
4d7e198
ed312af
 
 
 
 
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
# IIIF Studio β€” image de production (multi-stage)
# Ce fichier est utilisΓ© par HuggingFace Spaces (SDK docker, dΓ©tection automatique).
# Source unique β€” le fichier infra/Dockerfile a Γ©tΓ© supprimΓ© pour Γ©viter la divergence.
#
# Build depuis la racine du dΓ©pΓ΄t :
#   docker build -t iiif-studio .

# ── Stage 1 : build du frontend React ────────────────────────────────────────
FROM node:20-slim AS frontend-builder

WORKDIR /frontend

# Installer les dΓ©pendances (cache layer sΓ©parΓ©)
COPY frontend/package.json ./
RUN npm install

# Copier les sources et builder
COPY frontend/ ./
RUN npm run build

# ── Stage 2 : image Python finale ────────────────────────────────────────────
FROM python:3.11-slim

WORKDIR /app

# ── DΓ©pendances Python ─────────────────────────────────────────────────────
# On copie uniquement pyproject.toml pour exploiter le cache de layers Docker.
# Un stub app/__init__.py satisfait setuptools (discover packages) sans avoir
# besoin de copier tout le code source Γ  ce stade.
COPY backend/pyproject.toml /tmp/build/
RUN mkdir -p /tmp/build/app \
    && touch /tmp/build/app/__init__.py \
    && pip install --no-cache-dir --upgrade /tmp/build/ \
    && rm -rf /tmp/build

# ── Layer dΓ©diΓ© mistralai β€” garantit v1.x mΓͺme si le cache pip rΓ©sout autrement ──
# Layer sΓ©parΓ© pour s'assurer que mistralai>=1.0 est bien installΓ©.
# Sans cette ligne, une rΓ©solution de dΓ©pendances conflictuelle peut installer v0.x.
RUN pip install --no-cache-dir 'mistralai>=1.0,<2.0'

# ── Code source backend ────────────────────────────────────────────────────
COPY backend/app ./backend/app
COPY profiles/ ./profiles/
COPY prompts/ ./prompts/

# ── Frontend buildΓ© ────────────────────────────────────────────────────────
COPY --from=frontend-builder /frontend/dist ./static

# ── RΓ©pertoire des artefacts (vide dans l'image ; montΓ© en volume) ─────────
RUN mkdir -p /app/data

# ── Secrets : JAMAIS dans l'image (R06) ────────────────────────────────────
# Passer au runtime via les Secrets HuggingFace Spaces :
#   GOOGLE_AI_STUDIO_API_KEY, MISTRAL_API_KEY, VERTEX_SERVICE_ACCOUNT_JSON

# ── Utilisateur non-root (sΓ©curitΓ©) ───────────────────────────────────────
RUN adduser --disabled-password --gecos '' appuser && chown -R appuser:appuser /app
USER appuser

# PYTHONPATH permet l'import `app.main:app` depuis /app/backend/app/
ENV PYTHONPATH=/app/backend
ENV PROFILES_DIR=/app/profiles
ENV PROMPTS_DIR=/app/prompts
ENV DATA_DIR=/app/data

EXPOSE 7860

# 1 worker au MVP β€” pas de Gunicorn, pas de multiprocessing
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "7860", "--workers", "1"]