Files
e-cosplay/backup.sh

145 lines
5.8 KiB
Bash
Executable File

#!/bin/sh
set -eu
# ============================================================================
# E-COSPLAY - Script de sauvegarde pour migration vers un autre serveur
# ----------------------------------------------------------------------------
# N'UTILISE PAS DOCKER. S'appuie sur les binaires installés sur l'hôte
# (pg_dump, psql, tar, gzip) et lit DATABASE_URL depuis .env.local.
#
# Sauvegarde :
# - Base PostgreSQL distante via DATABASE_URL (pg_dump logique)
# - Fichiers uploadés (public/storage)
# - Fichiers d'environnement et credentials (.env.local, google.json, ...)
#
# Le tout est empaqueté dans une archive tar.gz horodatée.
# ============================================================================
RED='\033[0;31m'
ORANGE='\033[0;33m'
GREEN='\033[0;32m'
CYAN='\033[0;36m'
RESET='\033[0m'
PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$PROJECT_DIR"
TIMESTAMP="$(date +%Y%m%d_%H%M%S)"
BACKUP_DIR="${BACKUP_DIR:-$PROJECT_DIR/var/backups}"
WORK_DIR="$BACKUP_DIR/tmp_$TIMESTAMP"
ARCHIVE="$BACKUP_DIR/e-cosplay_backup_$TIMESTAMP.tar.gz"
STORAGE_DIR="${STORAGE_DIR:-public/storage}"
echo "${CYAN}############################${RESET}"
echo "${CYAN}# E-COSPLAY BACKUP START #${RESET}"
echo "${CYAN}############################${RESET}"
echo "${CYAN}Destination : ${ARCHIVE}${RESET}"
mkdir -p "$WORK_DIR"
# ---------------------------------------------------------------------------
# 1) Vérifications
# ---------------------------------------------------------------------------
for bin in pg_dump tar gzip; do
if ! command -v "$bin" >/dev/null 2>&1; then
echo "${RED}Binaire introuvable : $bin${RESET}" >&2
exit 1
fi
done
# ---------------------------------------------------------------------------
# 2) Récupération de DATABASE_URL
# Priorité : variable d'env existante > .env.local > .env.prod.local > .env
# ---------------------------------------------------------------------------
get_database_url() {
if [ -n "${DATABASE_URL:-}" ]; then
echo "$DATABASE_URL"
return 0
fi
for f in .env.local .env.prod.local .env.prod .env; do
if [ -f "$PROJECT_DIR/$f" ]; then
url="$(grep -E '^DATABASE_URL=' "$PROJECT_DIR/$f" | tail -n1 | sed -E 's/^DATABASE_URL=//; s/^"(.*)"$/\1/; s/^'"'"'(.*)'"'"'$/\1/')"
if [ -n "$url" ]; then
echo "$url"
return 0
fi
fi
done
return 1
}
DATABASE_URL_RAW="$(get_database_url || true)"
if [ -z "$DATABASE_URL_RAW" ]; then
echo "${RED}DATABASE_URL introuvable (ni en env, ni dans .env.local/.env)${RESET}" >&2
exit 1
fi
# Strip des paramètres Doctrine (serverVersion, charset, ...) que libpq ignore
DATABASE_URL_CLEAN="$(echo "$DATABASE_URL_RAW" | sed -E 's/\?.*$//')"
# Affiche une URL masquée (cache le mot de passe)
DATABASE_URL_MASKED="$(echo "$DATABASE_URL_CLEAN" | sed -E 's#(://[^:]+:)[^@]+(@)#\1***\2#')"
echo "${CYAN}> DATABASE_URL : ${DATABASE_URL_MASKED}${RESET}"
# ---------------------------------------------------------------------------
# 3) Dump PostgreSQL
# ---------------------------------------------------------------------------
echo "${CYAN}> Dump PostgreSQL...${RESET}"
pg_dump "$DATABASE_URL_CLEAN" \
--clean --if-exists --no-owner --no-privileges \
| gzip -9 > "$WORK_DIR/database.sql.gz"
echo "${GREEN} ✓ database.sql.gz ($(du -h "$WORK_DIR/database.sql.gz" | cut -f1))${RESET}"
# ---------------------------------------------------------------------------
# 4) Fichiers uploadés
# ---------------------------------------------------------------------------
if [ -d "$PROJECT_DIR/$STORAGE_DIR" ]; then
echo "${CYAN}> Sauvegarde de ${STORAGE_DIR}...${RESET}"
tar -C "$PROJECT_DIR" -czf "$WORK_DIR/storage.tar.gz" "$STORAGE_DIR"
echo "${GREEN} ✓ storage.tar.gz ($(du -h "$WORK_DIR/storage.tar.gz" | cut -f1))${RESET}"
else
echo "${ORANGE} ! ${STORAGE_DIR} introuvable, étape ignorée${RESET}"
fi
# ---------------------------------------------------------------------------
# 5) Fichiers d'environnement et credentials
# ---------------------------------------------------------------------------
echo "${CYAN}> Copie des fichiers d'environnement et credentials...${RESET}"
mkdir -p "$WORK_DIR/env"
for f in .env .env.local .env.prod .env.prod.local google.json account.json; do
if [ -f "$PROJECT_DIR/$f" ]; then
cp -a "$PROJECT_DIR/$f" "$WORK_DIR/env/$f"
echo "${GREEN}$f${RESET}"
fi
done
# ---------------------------------------------------------------------------
# 6) Métadonnées
# ---------------------------------------------------------------------------
{
echo "timestamp=$TIMESTAMP"
echo "hostname=$(hostname)"
echo "git_commit=$(git -C "$PROJECT_DIR" rev-parse HEAD 2>/dev/null || echo unknown)"
echo "git_branch=$(git -C "$PROJECT_DIR" rev-parse --abbrev-ref HEAD 2>/dev/null || echo unknown)"
echo "database_url=$DATABASE_URL_MASKED"
echo "storage_dir=$STORAGE_DIR"
} > "$WORK_DIR/manifest.txt"
# ---------------------------------------------------------------------------
# 7) Empaquetage final
# ---------------------------------------------------------------------------
echo "${CYAN}> Empaquetage de l'archive finale...${RESET}"
tar -C "$BACKUP_DIR" -czf "$ARCHIVE" "tmp_$TIMESTAMP"
rm -rf "$WORK_DIR"
echo "${GREEN}############################${RESET}"
echo "${GREEN}# BACKUP TERMINÉ #${RESET}"
echo "${GREEN}############################${RESET}"
echo "${GREEN}Archive : ${ARCHIVE}${RESET}"
echo "${GREEN}Taille : $(du -h "$ARCHIVE" | cut -f1)${RESET}"
echo
echo "${CYAN}Pour transférer vers le nouveau serveur :${RESET}"
echo " scp \"$ARCHIVE\" user@nouveau-serveur:/chemin/vers/e-cosplay/var/backups/"
echo " ssh user@nouveau-serveur 'cd /chemin/vers/e-cosplay && ./restore.sh \"var/backups/$(basename "$ARCHIVE")\"'"