#!/bin/bash # ============================================================================= # ObsiGate — Script de build et déploiement Docker # ============================================================================= # # Usage : # ./build.sh [--prod | --test-win | --test-linux] [OPTIONS] # # Environnements : # --prod Production (défaut) — docker-compose.yml # --test-win Test Windows (Docker Desktop) — docker-compose.test-win.yml # --test-linux Test Linux — docker-compose.test-linux.yml # # Options : # --help, -h Affiche cette aide # --build-only Construit l'image sans démarrer le conteneur # --no-cache Rebuild complet sans cache Docker (défaut) # --cache Utilise le cache Docker (plus rapide si peu de changements) # --progress=plain Sortie verbeuse (défaut: auto) # --progress=tty Sortie interactive (barres de progression) # # Étapes exécutées : # 1. Vérifie que Docker et Docker Compose sont installés # 2. Valide le fichier docker-compose choisi # 3. Crée les dossiers de test si nécessaire (modes test uniquement) # 4. Construit l'image Docker (multi-stage, ~180MB) # 5. Démarre le conteneur en arrière-plan # 6. Affiche le statut et les logs # # Exemples : # ./build.sh # Production # ./build.sh --test-win # Test Windows # ./build.sh --test-linux --cache # Test Linux avec cache # ./build.sh --test-win --build-only # Build test Windows sans démarrer # ============================================================================= set -euo pipefail # ----- Helpers ----- info() { printf '\033[1;34m[INFO]\033[0m %s\n' "$*"; } ok() { printf '\033[1;32m[OK]\033[0m %s\n' "$*"; } warn() { printf '\033[1;33m[WARN]\033[0m %s\n' "$*"; } error() { printf '\033[1;31m[ERR]\033[0m %s\n' "$*" >&2; } # ----- Usage ----- show_help() { awk '/^# =/{c++; if(c>=3)exit; next} c>=2{print}' "$0" | sed 's/^# //' exit 0 } # ----- Parse args ----- ENV_MODE="prod" COMPOSE_FILE="" BUILD_ONLY=false USE_CACHE=false BUILD_ARGS=() for arg in "$@"; do case "$arg" in --help|-h) show_help ;; --prod) ENV_MODE="prod" ;; --test-win) ENV_MODE="test-win" ;; --test-linux) ENV_MODE="test-linux" ;; --build-only) BUILD_ONLY=true ;; --no-cache) USE_CACHE=false ;; --cache) USE_CACHE=true ;; *) BUILD_ARGS+=("$arg") ;; esac done # ----- Select compose file ----- case "$ENV_MODE" in prod) COMPOSE_FILE="docker-compose.yml" COMPOSE_ENV_NAME="production" ;; test-win) COMPOSE_FILE="docker-compose.test-win.yml" COMPOSE_ENV_NAME="test Windows" ;; test-linux) COMPOSE_FILE="docker-compose.test-linux.yml" COMPOSE_ENV_NAME="test Linux" ;; *) error "Environnement inconnu : $ENV_MODE" exit 1 ;; esac # ----- Pre-flight checks ----- if ! command -v docker &>/dev/null; then error "Docker est introuvable. Installez Docker avant de continuer." exit 1 fi ok "Docker $(docker --version | grep -oP '\d+\.\d+\.\d+') détecté" COMPOSE_CMD="" if docker compose version &>/dev/null 2>&1; then COMPOSE_CMD="docker compose" elif docker-compose version &>/dev/null 2>&1; then COMPOSE_CMD="docker-compose" warn "Utilisation de docker-compose (legacy). Pensez à installer le plugin docker compose." else error "Docker Compose est introuvable. Installez-le : https://docs.docker.com/compose/install/" exit 1 fi ok "$($COMPOSE_CMD version --short 2>/dev/null || $COMPOSE_CMD version | head -1)" # ----- Validate compose file ----- if [[ ! -f "$COMPOSE_FILE" ]]; then error "$COMPOSE_FILE introuvable dans $(pwd)" exit 1 fi echo "" info "=== ObsiGate — Build & Deploy ($COMPOSE_ENV_NAME) ===" info "Fichier compose : $COMPOSE_FILE" # ----- Test mode: create test directories ----- if [[ "$ENV_MODE" == "test-win" ]]; then info "Création des dossiers de test Windows..." mkdir -p /c/dev/git/python/ObsiGate/test_vault mkdir -p /c/dev/git/python/ObsiGate/test_dir # Create a sample note for the test vault if [[ ! -f /c/dev/git/python/ObsiGate/test_vault/Accueil.md ]]; then echo "# Bienvenue dans le vault de test" > /c/dev/git/python/ObsiGate/test_vault/Accueil.md echo "" >> /c/dev/git/python/ObsiGate/test_vault/Accueil.md echo "Ce vault est utilisé pour les tests de développement d'ObsiGate." >> /c/dev/git/python/ObsiGate/test_vault/Accueil.md ok "Note de test créée : test_vault/Accueil.md" fi elif [[ "$ENV_MODE" == "test-linux" ]]; then info "Création des dossiers de test Linux..." mkdir -p /tmp/obsigate-test-vault mkdir -p /tmp/obsigate-test-dir mkdir -p /tmp/obsigate-test-data chmod -R 777 /tmp/obsigate-test-data 2>/dev/null || true if [[ ! -f /tmp/obsigate-test-vault/Accueil.md ]]; then echo "# Bienvenue dans le vault de test" > /tmp/obsigate-test-vault/Accueil.md echo "" >> /tmp/obsigate-test-vault/Accueil.md echo "Ce vault est utilisé pour les tests de développement d'ObsiGate." >> /tmp/obsigate-test-vault/Accueil.md ok "Note de test créée : test-vault/Accueil.md" fi fi # ----- Extract volume mount paths and warn about missing ones ----- info "Vérification des volumes montés sur le host..." VOLUME_COUNT=0 MISSING_COUNT=0 while IFS= read -r line; do if [[ "$line" =~ ^[[:space:]]*-[[:space:]]+(/[^:]+): ]]; then host_path="${BASH_REMATCH[1]}" VOLUME_COUNT=$((VOLUME_COUNT + 1)) if [[ ! -d "$host_path" && ! -f "$host_path" ]]; then warn "Volume source absent : $host_path (le conteneur créera un dossier vide)" MISSING_COUNT=$((MISSING_COUNT + 1)) else ok "Volume trouvé : $host_path" fi fi done < <(grep -E '^\s+-\s+/' "$COMPOSE_FILE") if [[ "$VOLUME_COUNT" -eq 0 ]]; then warn "Aucun volume host détecté dans $COMPOSE_FILE." fi if [[ "$MISSING_COUNT" -gt 0 ]]; then warn "$MISSING_COUNT volume(s) absent(s). Vérifiez vos chemins dans $COMPOSE_FILE." fi echo "" # ----- Build the image ----- BUILD_FLAGS=() if [[ "$USE_CACHE" == false ]]; then BUILD_FLAGS+=(--no-cache) info "Construction de l'image Docker (sans cache)..." else info "Construction de l'image Docker (avec cache)..." fi # Version livrée : le fichier VERSION (racine du dépôt) est la source unique de # vérité ; le Dockerfile le copie dans l'image. Aucun numéro codé en dur ici. VERSION=$(cat VERSION 2>/dev/null | tr -d '[:space:]' | sed 's/^v//' || true) [ -n "$VERSION" ] || VERSION="0.0.0" export VERSION info "Version: $VERSION" $COMPOSE_CMD -f "$COMPOSE_FILE" build "${BUILD_FLAGS[@]}" "${BUILD_ARGS[@]}" ok "Image construite avec succès" # ----- Stop if build-only ----- if [[ "$BUILD_ONLY" == true ]]; then echo "" info "Mode build-only : conteneur non démarré." info "Pour démarrer manuellement : $COMPOSE_CMD -f $COMPOSE_FILE up -d" exit 0 fi # ----- Start the container ----- info "Démarrage du conteneur..." $COMPOSE_CMD -f "$COMPOSE_FILE" up -d --remove-orphans ok "Conteneur démarré" # ----- Show status ----- echo "" info "Statut du conteneur :" $COMPOSE_CMD -f "$COMPOSE_FILE" ps echo "" info "Logs récents (Ctrl+C pour quitter) :" $COMPOSE_CMD -f "$COMPOSE_FILE" logs --tail=20