oc_mlops_projet_3 / start.sh
CedM's picture
Déploiement automatique depuis GitLab CI
1684853 verified
#!/bin/bash
# =============================================================================
# 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