#!/bin/sh set -eu # ============================================================================ # E-COSPLAY - Script de restauration sur un nouveau serveur # ---------------------------------------------------------------------------- # N'UTILISE PAS DOCKER. S'appuie sur les binaires installés sur l'hôte # (psql, tar, gunzip) et lit DATABASE_URL depuis .env.local après l'avoir # restauré depuis l'archive. # # Usage : ./restore.sh # # Étapes : # 1. Décompresse l'archive # 2. Restaure les fichiers d'environnement (.env.local, etc.) # 3. Restaure la base PostgreSQL via psql + DATABASE_URL # 4. Restaure les fichiers uploadés (public/storage) # 5. Vide le cache Symfony et applique les migrations Doctrine # # ATTENTION : la restauration ÉCRASE les données existantes (DB + storage). # ============================================================================ RED='\033[0;31m' ORANGE='\033[0;33m' GREEN='\033[0;32m' CYAN='\033[0;36m' RESET='\033[0m' if [ $# -lt 1 ]; then echo "${RED}Usage : $0 ${RESET}" >&2 exit 1 fi ARCHIVE="$1" if [ ! -f "$ARCHIVE" ]; then echo "${RED}Archive introuvable : $ARCHIVE${RESET}" >&2 exit 1 fi PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)" cd "$PROJECT_DIR" case "$ARCHIVE" in /*) ARCHIVE_ABS="$ARCHIVE" ;; *) ARCHIVE_ABS="$(pwd)/$ARCHIVE" ;; esac STORAGE_DIR="${STORAGE_DIR:-public/storage}" WORK_DIR="$(mktemp -d /tmp/e-cosplay_restore.XXXXXX)" trap 'rm -rf "$WORK_DIR"' EXIT echo "${CYAN}#############################${RESET}" echo "${CYAN}# E-COSPLAY RESTORE START #${RESET}" echo "${CYAN}#############################${RESET}" echo "${CYAN}Archive : ${ARCHIVE_ABS}${RESET}" # --------------------------------------------------------------------------- # Vérifications # --------------------------------------------------------------------------- for bin in psql tar gunzip; do if ! command -v "$bin" >/dev/null 2>&1; then echo "${RED}Binaire introuvable : $bin${RESET}" >&2 exit 1 fi done # --------------------------------------------------------------------------- # Confirmation interactive (skip avec FORCE=1) # --------------------------------------------------------------------------- if [ "${FORCE:-0}" != "1" ]; then printf "${ORANGE}La restauration va ÉCRASER la base et les fichiers existants. Continuer ? [y/N] ${RESET}" read -r answer case "$answer" in y|Y|yes|YES) ;; *) echo "Annulé."; exit 0 ;; esac fi # --------------------------------------------------------------------------- # 1) Décompression # --------------------------------------------------------------------------- echo "${CYAN}> Décompression de l'archive...${RESET}" tar -xzf "$ARCHIVE_ABS" -C "$WORK_DIR" SRC="$(find "$WORK_DIR" -mindepth 1 -maxdepth 1 -type d | head -n1)" if [ -z "$SRC" ] || [ ! -f "$SRC/manifest.txt" ]; then echo "${RED}Archive invalide : manifest.txt introuvable${RESET}" >&2 exit 1 fi echo "${GREEN} ✓ Manifest :${RESET}" sed 's/^/ /' "$SRC/manifest.txt" # --------------------------------------------------------------------------- # 2) Restauration des fichiers d'environnement # --------------------------------------------------------------------------- if [ -d "$SRC/env" ]; then echo "${CYAN}> Restauration des fichiers d'environnement...${RESET}" for f in "$SRC"/env/*; do [ -e "$f" ] || continue name="$(basename "$f")" if [ -f "$PROJECT_DIR/$name" ]; then cp -a "$PROJECT_DIR/$name" "$PROJECT_DIR/$name.bak.$(date +%s)" fi cp -a "$f" "$PROJECT_DIR/$name" echo "${GREEN} ✓ $name${RESET}" done fi # --------------------------------------------------------------------------- # 3) Récupération de DATABASE_URL (après restauration des fichiers 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${RESET}" >&2 exit 1 fi DATABASE_URL_CLEAN="$(echo "$DATABASE_URL_RAW" | sed -E 's/\?.*$//')" DATABASE_URL_MASKED="$(echo "$DATABASE_URL_CLEAN" | sed -E 's#(://[^:]+:)[^@]+(@)#\1***\2#')" echo "${CYAN}> DATABASE_URL : ${DATABASE_URL_MASKED}${RESET}" # --------------------------------------------------------------------------- # 4) Restauration PostgreSQL # --------------------------------------------------------------------------- if [ -f "$SRC/database.sql.gz" ]; then echo "${CYAN}> Restauration de la base PostgreSQL...${RESET}" gunzip -c "$SRC/database.sql.gz" \ | psql "$DATABASE_URL_CLEAN" -v ON_ERROR_STOP=1 >/dev/null echo "${GREEN} ✓ Base restaurée${RESET}" else echo "${ORANGE} ! database.sql.gz absent, étape ignorée${RESET}" fi # --------------------------------------------------------------------------- # 5) Restauration des fichiers uploadés # --------------------------------------------------------------------------- if [ -f "$SRC/storage.tar.gz" ]; then echo "${CYAN}> Restauration de ${STORAGE_DIR}...${RESET}" if [ -d "$PROJECT_DIR/$STORAGE_DIR" ]; then backup_path="$PROJECT_DIR/${STORAGE_DIR}.bak.$(date +%s)" mv "$PROJECT_DIR/$STORAGE_DIR" "$backup_path" echo "${ORANGE} ! ancien dossier déplacé vers $backup_path${RESET}" fi tar -xzf "$SRC/storage.tar.gz" -C "$PROJECT_DIR" echo "${GREEN} ✓ ${STORAGE_DIR} restauré${RESET}" else echo "${ORANGE} ! storage.tar.gz absent, étape ignorée${RESET}" fi # --------------------------------------------------------------------------- # 6) Cache Symfony + migrations Doctrine # --------------------------------------------------------------------------- if [ -x "$PROJECT_DIR/bin/console" ] && command -v php >/dev/null 2>&1; then echo "${CYAN}> Vidage du cache Symfony...${RESET}" php "$PROJECT_DIR/bin/console" cache:clear --no-warmup || true php "$PROJECT_DIR/bin/console" cache:warmup || true echo "${CYAN}> Application des migrations Doctrine éventuelles...${RESET}" php "$PROJECT_DIR/bin/console" doctrine:migrations:migrate --no-interaction --allow-no-migration || true fi echo "${GREEN}#############################${RESET}" echo "${GREEN}# RESTORE TERMINÉ #${RESET}" echo "${GREEN}#############################${RESET}" echo "${GREEN}Pense à vérifier :${RESET}" echo " - les variables d'environnement spécifiques au nouveau serveur (PATH_URL, DEV_URL, ...)" echo " - les permissions du dossier $STORAGE_DIR (utilisateur du serveur web)" echo " - la conf Caddy / Nginx / Apache et les certificats TLS"