#!/usr/bin/env bash set -euo pipefail # ========================= # Deploy PROD webval (Jetson) # Repo -> /var/www/mathematiques # Backup + exclusions + rollback # ========================= APP_NAME="webval" SRC_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DST_DIR="/var/www/mathematiques" # Dossier backups (hors web) BACKUP_ROOT="/var/backups/${APP_NAME}" TS="$(date +%Y%m%d_%H%M%S)" BACKUP_DIR="${BACKUP_ROOT}/prev_${TS}" # URL de check (adapte si besoin) HEALTH_URL="http://127.0.0.1/" HEALTH_TIMEOUT=10 # Exclusions: runtime + config sensible + git RSYNC_EXCLUDES=( ".git/" "evaluations/" "evaluations_transit/" "uploads/" "logs/" "temp/" "backup/" "backups/" "config/database.php" "config/secrets.php" "config/db_credentials.txt" ) # --- helpers --- die() { echo "ERREUR: $*" >&2; exit 1; } print_excludes() { for e in "${RSYNC_EXCLUDES[@]}"; do echo " - $e" done } rsync_exclude_args() { for e in "${RSYNC_EXCLUDES[@]}"; do printf -- "--exclude=%q " "$e" done } need_cmd() { command -v "$1" >/dev/null 2>&1 || die "Commande manquante: $1" } healthcheck() { # Healthcheck simple: HTTP 200/301/302 attendu sur la home # (Si ton app a une URL spécifique de health, mets-la dans HEALTH_URL) if curl -fsS -m "${HEALTH_TIMEOUT}" -o /dev/null -I "${HEALTH_URL}"; then return 0 fi return 1 } rollback() { echo echo "=== ROLLBACK ===" echo "Restauration depuis: ${BACKUP_DIR}" if [[ ! -d "${BACKUP_DIR}" ]]; then die "Backup introuvable, rollback impossible: ${BACKUP_DIR}" fi sudo rsync -a --delete "${BACKUP_DIR}/" "${DST_DIR}/" sudo systemctl reload php8.1-fpm >/dev/null 2>&1 || true sudo systemctl reload nginx >/dev/null 2>&1 || true echo "Rollback terminé." } # --- prérequis --- need_cmd rsync need_cmd curl need_cmd date echo "=== Deploy PROD (${APP_NAME}) ===" echo "Source: ${SRC_DIR}" echo "Dest : ${DST_DIR}" echo "Backup: ${BACKUP_DIR}" echo echo "Exclusions:" print_excludes echo [[ -d "${SRC_DIR}/.git" ]] || die "Pas de .git dans ${SRC_DIR} (pas un repo ?)." [[ -d "${DST_DIR}" ]] || die "Destination inexistante: ${DST_DIR}" # Si tu veux empêcher un deploy avec un working tree sale: if ! git -C "${SRC_DIR}" diff --quiet || ! git -C "${SRC_DIR}" diff --cached --quiet; then echo "AVERTISSEMENT: ton repo a des modifications non commit." echo "Tu peux quand même déployer, mais c'est risqué." read -r -p "Continuer malgré tout ? (oui/non) " ans_dirty [[ "${ans_dirty}" == "oui" ]] || exit 0 fi # --- aperçu --- echo "--- Aperçu (dry-run) ---" # shellcheck disable=SC2046 sudo rsync -a --delete --dry-run \ $(rsync_exclude_args) \ "${SRC_DIR}/" "${DST_DIR}/" | sed -n '1,200p' echo "(aperçu tronqué à 200 lignes)" echo read -r -p "Lancer le backup + déploiement maintenant ? (oui/non) " ans [[ "${ans}" == "oui" ]] || { echo "Annulé."; exit 0; } # --- backup --- echo echo "--- Backup PROD -> ${BACKUP_DIR} ---" sudo mkdir -p "${BACKUP_ROOT}" sudo rsync -a --delete "${DST_DIR}/" "${BACKUP_DIR}/" # --- deploy --- echo echo "--- Déploiement ---" # shellcheck disable=SC2046 sudo rsync -a --delete \ $(rsync_exclude_args) \ "${SRC_DIR}/" "${DST_DIR}/" # --- reload --- echo echo "--- Reload services ---" sudo systemctl reload php8.1-fpm >/dev/null 2>&1 || true sudo systemctl reload nginx >/dev/null 2>&1 || true # --- healthcheck --- echo echo "--- Healthcheck: ${HEALTH_URL} ---" if healthcheck; then echo "OK: deploy réussi." echo "Backup conservé: ${BACKUP_DIR}" exit 0 fi echo "ECHEC: healthcheck KO. On rollback." rollback echo echo "Après rollback, je te conseille de regarder :" echo " - sudo tail -n 80 /var/log/nginx/error.log" echo " - sudo journalctl -u php8.1-fpm -n 80 --no-pager" exit 2