Spaces:
Sleeping
Sleeping
| # ============================================================================= | |
| # start.sh — Script de démarrage HuggingFace Spaces | |
| # | |
| # Rôle : | |
| # 1. Initialise le cluster PostgreSQL (premier démarrage uniquement) | |
| # 2. Crée la base, applique le schéma et crée l'utilisateur read-only | |
| # 3. Démarre PostgreSQL en tâche de fond | |
| # 4. Lance Streamlit en premier plan (PID 1 du conteneur) | |
| # | |
| # Variables d'environnement attendues (Secrets HF Spaces) : | |
| # POSTGRES_PASSWORD — mot de passe du superutilisateur 'admin' | |
| # PG_USER_1_PASSWORD — mot de passe de l'utilisateur read-only 'user_1' | |
| # MISTRAL_API_KEY — clé API Mistral | |
| # LOGFIRE_TOKEN — (optionnel) token Logfire | |
| # ============================================================================= | |
| set -e | |
| # --------------------------------------------------------------------------- | |
| # Valeurs par défaut (peuvent être surchargées par les Secrets HF) | |
| # --------------------------------------------------------------------------- | |
| PGDATA="${PGDATA:-/home/user/pgdata}" | |
| PG_DB="${PG_DB:-oc_mlops_projet_3}" | |
| PG_ADMIN="${PG_ADMIN:-admin}" | |
| PG_PORT="${PG_PORT:-5432}" | |
| POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-changeme_set_in_hf_secrets}" | |
| PG_USER_1_PASSWORD="${PG_USER_1_PASSWORD:-readonly_set_in_hf_secrets}" | |
| APP_DIR="/home/user/app" | |
| SQL_DIR="$APP_DIR/sql" | |
| PG_LOG="/tmp/postgresql.log" | |
| # --------------------------------------------------------------------------- | |
| # Étape 1 — Initialisation du cluster PostgreSQL (premier démarrage) | |
| # --------------------------------------------------------------------------- | |
| if [ ! -f "$PGDATA/PG_VERSION" ]; then | |
| echo "🔧 [PG] Initialisation du cluster PostgreSQL dans $PGDATA ..." | |
| mkdir -p "$PGDATA" | |
| # initdb crée le cluster ; l'utilisateur courant (UID 1000) devient superutilisateur | |
| # --username définit le nom du superutilisateur PostgreSQL | |
| # --pwfile définit son mot de passe depuis un fd temporaire (évite l'exposition dans les logs) | |
| initdb \ | |
| -D "$PGDATA" \ | |
| --username="$PG_ADMIN" \ | |
| --pwfile=<(printf '%s' "$POSTGRES_PASSWORD") \ | |
| --auth-host=md5 \ | |
| --auth-local=md5 \ | |
| -E UTF8 \ | |
| --locale=C \ | |
| > /tmp/initdb.log 2>&1 | |
| # Configuration réseau : écoute uniquement sur localhost | |
| echo "listen_addresses = '127.0.0.1'" >> "$PGDATA/postgresql.conf" | |
| echo "port = $PG_PORT" >> "$PGDATA/postgresql.conf" | |
| # HF Spaces tourne en non-root : /var/run/postgresql n'est pas accessible. | |
| # On redirige le socket Unix vers /tmp (toujours accessible à UID 1000). | |
| echo "unix_socket_directories = '/tmp'" >> "$PGDATA/postgresql.conf" | |
| echo "✅ [PG] Cluster initialisé." | |
| # ----------------------------------------------------------------------- | |
| # Démarrage temporaire pour créer la base et le schéma | |
| # ----------------------------------------------------------------------- | |
| echo "🚀 [PG] Démarrage temporaire pour l'initialisation ..." | |
| pg_ctl -D "$PGDATA" -l "$PG_LOG" start -w -t 60 || { echo "❌ [PG] Échec du démarrage. Log :"; cat "$PG_LOG"; exit 1; } | |
| echo "📦 [PG] Création de la base '$PG_DB' ..." | |
| PGPASSWORD="$POSTGRES_PASSWORD" createdb \ | |
| -h 127.0.0.1 -p "$PG_PORT" -U "$PG_ADMIN" \ | |
| "$PG_DB" | |
| echo "📐 [PG] Application du schéma relationnel ..." | |
| PGPASSWORD="$POSTGRES_PASSWORD" psql \ | |
| -h 127.0.0.1 -p "$PG_PORT" \ | |
| -U "$PG_ADMIN" -d "$PG_DB" \ | |
| -f "$SQL_DIR/01_schema.sql" \ | |
| > /tmp/schema_init.log 2>&1 | |
| echo "👤 [PG] Création de l'utilisateur read-only 'user_1' ..." | |
| PGPASSWORD="$POSTGRES_PASSWORD" psql \ | |
| -h 127.0.0.1 -p "$PG_PORT" \ | |
| -U "$PG_ADMIN" -d "$PG_DB" << SQL | |
| CREATE ROLE user_1 WITH LOGIN NOINHERIT PASSWORD '$PG_USER_1_PASSWORD'; | |
| GRANT CONNECT ON DATABASE $PG_DB TO user_1; | |
| GRANT USAGE ON SCHEMA public TO user_1; | |
| GRANT SELECT ON ALL TABLES IN SCHEMA public TO user_1; | |
| SQL | |
| echo "⏹️ [PG] Arrêt du démarrage temporaire ..." | |
| pg_ctl -D "$PGDATA" stop | |
| echo "✅ [PG] Initialisation terminée." | |
| fi | |
| # --------------------------------------------------------------------------- | |
| # Étape 2 — Démarrage de PostgreSQL en tâche de fond | |
| # --------------------------------------------------------------------------- | |
| echo "🚀 [PG] Démarrage de PostgreSQL (port $PG_PORT) ..." | |
| pg_ctl -D "$PGDATA" -l "$PG_LOG" start -w -t 60 || { echo "❌ [PG] Échec du démarrage. Log :"; cat "$PG_LOG"; exit 1; } | |
| echo "✅ [PG] PostgreSQL démarré." | |
| # --------------------------------------------------------------------------- | |
| # Étape 3 — Démarrage de Streamlit en premier plan (port 7860, HF Spaces) | |
| # --------------------------------------------------------------------------- | |
| echo "🚀 [Streamlit] Démarrage sur le port 7860 ..." | |
| cd "$APP_DIR" | |
| exec streamlit run MistralChat.py \ | |
| --server.port=7860 \ | |
| --server.address=0.0.0.0 \ | |
| --server.headless=true \ | |
| --browser.gatherUsageStats=false | |