From 2d7ad3ae761101a8d20a665886c3007d8d46a2b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Mureau?= Date: Fri, 11 Jul 2025 07:22:55 +0200 Subject: [PATCH] Dockerfile deployment on Google Cloud is now working. --- deployment/api/Dockerfile | 25 +++++++++++++------------ deployment/api/app.py | 4 +++- deployment/api/main.py | 3 ++- deployment/api/nginx.conf | 14 ++++++++------ deployment/api/start.sh | 36 ++++++++++++++++++++++++++++-------- 5 files changed, 54 insertions(+), 28 deletions(-) diff --git a/deployment/api/Dockerfile b/deployment/api/Dockerfile index 302a15f..2a0847b 100644 --- a/deployment/api/Dockerfile +++ b/deployment/api/Dockerfile @@ -2,32 +2,33 @@ FROM python:3.12-slim WORKDIR /app -# Mettre à jour les packages et installer nginx +# # Install nginx and system packages RUN apt-get update && \ - apt-get install -y nginx && \ + apt-get install -y nginx curl && \ + # Créer l'utilisateur et le groupe www-data si ce n'est pas déjà fait par l'image de base + # Assurer que l'utilisateur nginx (souvent www-data) a un ID consistent + adduser --system --no-create-home --group www-data || true && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* -# Copier les fichiers de requirements et installer les dépendances Python +# Copy and install Python dependencies COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt -# Copier le code de l'application +# Copy app code and configs COPY . . -# Copier la configuration nginx +# Copy nginx config - l'emplacement par défaut de Nginx est /etc/nginx/nginx.conf COPY nginx.conf /etc/nginx/nginx.conf -# Créer les répertoires nécessaires pour nginx -RUN mkdir -p /var/log/nginx && \ - mkdir -p /var/lib/nginx && \ - mkdir -p /run +# Pas besoin de créer les dossiers ici, le start.sh s'en chargera avec les bonnes permissions +RUN mkdir -p /var/log/nginx /var/lib/nginx /run -# Donner les droits d'exécution au script de démarrage +# Ensure script is executable RUN chmod +x /app/start.sh -# Exposer le port 8080 +# Expose only NGINX port (Cloud Run utilise 8080 par défaut) EXPOSE 8080 -# Lancer le script de démarrage +# Start everything via script CMD ["/app/start.sh"] diff --git a/deployment/api/app.py b/deployment/api/app.py index 3cd4db4..b296a03 100644 --- a/deployment/api/app.py +++ b/deployment/api/app.py @@ -1,9 +1,11 @@ +import os import streamlit as st import requests +API_BASE_URL = os.getenv("API_BASE_URL", "http://127.0.0.1:8080") + "/api" + st.title("Analyse de Sentiment - Air Paradis") -API_BASE_URL = "http://127.0.0.1:8000" tweet = st.text_area("Entrez votre tweet ici :", height=150) diff --git a/deployment/api/main.py b/deployment/api/main.py index 9a4678b..c51bec6 100644 --- a/deployment/api/main.py +++ b/deployment/api/main.py @@ -69,7 +69,6 @@ def load_model_and_artifacts(model_name=MODEL_NAME, stage=STAGE): # Déterminer les chemins des artefacts local_dir = "./downloaded_artifacts" os.makedirs(local_dir, exist_ok=True) - print("Contenu de downloaded_artifacts :", os.listdir(local_dir)) base_path = "local_artifacts" tokenizer_file = "tokenizer.pickle" @@ -88,6 +87,8 @@ def load_model_and_artifacts(model_name=MODEL_NAME, stage=STAGE): # 🔽 Télécharger les artefacts model_path = dl(keras_file) tokenizer_path = dl(tokenizer_file) + print("Contenu de downloaded_artifacts :", os.listdir(local_dir)) + # 📦 Chargement model = load_model(model_path) diff --git a/deployment/api/nginx.conf b/deployment/api/nginx.conf index de209c9..09bcf1a 100644 --- a/deployment/api/nginx.conf +++ b/deployment/api/nginx.conf @@ -6,10 +6,7 @@ http { server { listen 8080; - # Proxy pour le backend FastAPI location /api/ { - # Le / à la fin de proxy_pass est important, - # il retire /api/ avant de le transmettre à FastAPI. proxy_pass http://127.0.0.1:8000/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; @@ -17,18 +14,23 @@ http { proxy_set_header X-Forwarded-Proto $scheme; } - # Proxy pour le frontend Streamlit location / { - # Le / à la fin est crucial pour que Streamlit fonctionne bien proxy_pass http://127.0.0.1:8501/; + proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; - proxy_read_timeout 86400; # Empêche les timeouts sur les connexions longues } + + location /health { + return 200 'OK'; + add_header Content-Type text/plain; + } + } } diff --git a/deployment/api/start.sh b/deployment/api/start.sh index ecd0379..5231fdd 100644 --- a/deployment/api/start.sh +++ b/deployment/api/start.sh @@ -1,15 +1,35 @@ #!/bin/bash -# Lancer Streamlit en arrière-plan avec un baseUrlPath dédié +set -e + +# S'assurer que les répertoires de cache et de log Nginx sont accessibles en écriture +mkdir -p /var/cache/nginx /var/run/nginx /var/log/nginx +chown -R www-data:www-data /var/cache/nginx /var/run/nginx /var/log/nginx + +echo "Starting Streamlit..." streamlit run app.py \ --server.port 8501 \ - --server.address 127.0.0.1 \ - --server.baseUrlPath "/app" \ + --server.address 0.0.0.0 \ --server.enableXsrfProtection false \ - & + --server.enableCORS false \ + & # Lance en arrière-plan -# Lancer Uvicorn en arrière-plan -uvicorn main:app --host 127.0.0.1 --port 8000 --loop asyncio & +echo "Starting FastAPI..." +uvicorn main:app --host 0.0.0.0 --port 8000 --loop asyncio & # Lance en arrière-plan -# Lancer nginx au premier plan (Docker suit ce processus) -nginx -g 'daemon off;' +# MODIFICATION IMPORTANTE ICI: Vérifier Streamlit sur le bon chemin +echo "Waiting for Streamlit to be ready..." +until curl -s http://127.0.0.1:8501 > /dev/null; do + sleep 1 +done +echo "Streamlit is ready!" + +# MODIFICATION: Vérifier FastAPI sur un endpoint existant, par exemple /docs ou /health +echo "Waiting for FastAPI to be ready..." +until curl -s http://127.0.0.1:8000/docs > /dev/null; do # Assurez-vous que /docs est un endpoint léger + sleep 1 +done +echo "FastAPI is ready!" + +echo "Launching NGINX..." +nginx -c /etc/nginx/nginx.conf -g 'daemon off;'