Add deploy_prod.sh (backup + rollback + exclusions)

This commit is contained in:
nicoboy
2026-01-02 15:33:47 +01:00
parent f8b8c0bf67
commit 3603ad5e61

155
deploy_prod.sh Executable file
View File

@ -0,0 +1,155 @@
#!/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