Files
e-ticket/backup.sh
Serreau Jovann 238ded3f54 Fix cp recursive flag for config/cert/ in backup.sh and restore.sh
Remplace 'cp -p' par 'cp -rp' lors de la copie de config/cert/.
Sans l'option -r, cp omet le repertoire avec l'erreur:
  cp: -r non specifie ; omission du repertoire 'config/cert/.'

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 13:29:45 +02:00

174 lines
6.2 KiB
Bash
Executable File

#!/bin/bash
# E-Ticket - Script d'export pour migration de serveur
# Genere un bundle complet et autonome pour migrer l'application sur un autre serveur.
#
# Le bundle contient:
# - dump de la base PostgreSQL (db.sql.gz)
# - uploads Vich/Flysystem (events, billets, logos) (public_uploads.tar.gz)
# - etat applicatif var/ (var_state.tar.gz)
# payouts/, billets/, invoices/, unsubscribed.json
# - configuration runtime sensible (env.local, cert/)
# - manifest avec checksums SHA-256 (manifest.txt)
#
# Le tout est ensuite empaquete dans une archive .tar.gz transferable par scp/rsync.
#
# Usage:
# ./backup.sh [DOSSIER_DESTINATION]
#
# Variables d'environnement supportees:
# COMPOSE_FILE : fichier docker-compose a utiliser (defaut: docker-compose-prod.yml)
# DB_SERVICE : service Docker de la base (defaut: db-master)
# DB_USER : utilisateur PostgreSQL (defaut: e-ticket)
# DB_NAME : base de donnees a exporter (defaut: e-ticket)
# SKIP_SECRETS : '1' pour exclure .env.local + cert (defaut: inclus)
set -euo pipefail
# --- Configuration ---
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DEST_DIR="${1:-${SCRIPT_DIR}/var/migration}"
COMPOSE_FILE="${COMPOSE_FILE:-${SCRIPT_DIR}/docker-compose-prod.yml}"
DB_SERVICE="${DB_SERVICE:-db-master}"
DB_USER="${DB_USER:-e-ticket}"
DB_NAME="${DB_NAME:-e-ticket}"
SKIP_SECRETS="${SKIP_SECRETS:-0}"
DATE="$(date +%Y%m%d_%H%M%S)"
BUNDLE_NAME="e_ticket_migration_${DATE}"
WORK_DIR="${DEST_DIR}/${BUNDLE_NAME}"
BUNDLE_FILE="${DEST_DIR}/${BUNDLE_NAME}.tar.gz"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}
err() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERREUR: $*" >&2
}
cleanup() {
if [ -d "${WORK_DIR}" ]; then
rm -rf "${WORK_DIR}"
fi
}
# Cleanup du WORK_DIR meme en cas d'erreur (le BUNDLE_FILE final reste)
trap cleanup EXIT
# --- Verifications prealables ---
if [ ! -f "${COMPOSE_FILE}" ]; then
err "Fichier docker-compose introuvable: ${COMPOSE_FILE}"
exit 1
fi
if ! docker compose -f "${COMPOSE_FILE}" ps --services --status running 2>/dev/null | grep -qx "${DB_SERVICE}"; then
err "Le service '${DB_SERVICE}' n'est pas demarre"
err "Demarrer la stack avec: make start_prod"
exit 1
fi
mkdir -p "${WORK_DIR}"
log "=== Export de migration E-Ticket ==="
log "Bundle: ${BUNDLE_NAME}"
log "Destination: ${DEST_DIR}"
# --- 1. Dump base de donnees ---
log "[1/5] Dump PostgreSQL '${DB_NAME}' depuis ${DB_SERVICE}..."
if ! docker compose -f "${COMPOSE_FILE}" exec -T "${DB_SERVICE}" \
pg_dump -U "${DB_USER}" -d "${DB_NAME}" \
--clean --if-exists --no-owner --no-privileges --quote-all-identifiers \
| gzip > "${WORK_DIR}/db.sql.gz"; then
err "Echec du dump PostgreSQL"
exit 1
fi
if [ ! -s "${WORK_DIR}/db.sql.gz" ]; then
err "Le dump PostgreSQL est vide"
exit 1
fi
log " OK ($(du -h "${WORK_DIR}/db.sql.gz" | cut -f1))"
# --- 2. Uploads publics (events, billets, logos) ---
log "[2/5] Archivage public/uploads (events, billets, logos)..."
if [ -d "${SCRIPT_DIR}/public/uploads" ]; then
tar -czf "${WORK_DIR}/public_uploads.tar.gz" -C "${SCRIPT_DIR}/public" uploads
log " OK ($(du -h "${WORK_DIR}/public_uploads.tar.gz" | cut -f1))"
else
err "public/uploads introuvable"
exit 1
fi
# --- 3. Etat applicatif var/ (PDFs generes, desinscrits...) ---
log "[3/5] Archivage etat applicatif var/ (payouts, billets, invoices, unsubscribed.json)..."
VAR_ITEMS=()
for item in payouts billets invoices unsubscribed.json; do
if [ -e "${SCRIPT_DIR}/var/${item}" ]; then
VAR_ITEMS+=("${item}")
fi
done
if [ ${#VAR_ITEMS[@]} -gt 0 ]; then
tar -czf "${WORK_DIR}/var_state.tar.gz" -C "${SCRIPT_DIR}/var" "${VAR_ITEMS[@]}"
log " OK - elements inclus: ${VAR_ITEMS[*]} ($(du -h "${WORK_DIR}/var_state.tar.gz" | cut -f1))"
else
log " Aucun element a archiver dans var/ (saut)"
fi
# --- 4. Configuration runtime sensible ---
if [ "${SKIP_SECRETS}" = "1" ]; then
log "[4/5] Secrets exclus (SKIP_SECRETS=1)"
log " ATTENTION: vous devrez deployer .env.local et config/cert/ manuellement sur le nouveau serveur"
else
log "[4/5] Archivage configuration sensible (.env.local + config/cert/)..."
SECRET_ITEMS=()
if [ -f "${SCRIPT_DIR}/.env.local" ]; then
cp -p "${SCRIPT_DIR}/.env.local" "${WORK_DIR}/env.local"
chmod 600 "${WORK_DIR}/env.local"
SECRET_ITEMS+=(".env.local")
fi
if [ -d "${SCRIPT_DIR}/config/cert" ]; then
mkdir -p "${WORK_DIR}/cert"
cp -rp "${SCRIPT_DIR}/config/cert/." "${WORK_DIR}/cert/"
chmod -R go-rwx "${WORK_DIR}/cert"
SECRET_ITEMS+=("config/cert/")
fi
if [ ${#SECRET_ITEMS[@]} -gt 0 ]; then
log " OK - elements inclus: ${SECRET_ITEMS[*]}"
else
log " Aucun secret trouve a archiver (saut)"
fi
fi
# --- 5. Manifest avec checksums et metadata ---
log "[5/5] Generation du manifest..."
{
echo "# E-Ticket migration bundle"
echo "bundle_name: ${BUNDLE_NAME}"
echo "created_at: $(date --iso-8601=seconds)"
echo "source_host: $(hostname)"
echo "git_commit: $(git -C "${SCRIPT_DIR}" rev-parse HEAD 2>/dev/null || echo 'unknown')"
echo "git_branch: $(git -C "${SCRIPT_DIR}" rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'unknown')"
echo "db_name: ${DB_NAME}"
echo "db_user: ${DB_USER}"
echo "skip_secrets: ${SKIP_SECRETS}"
echo
echo "# SHA-256 checksums"
(cd "${WORK_DIR}" && find . -type f ! -name 'manifest.txt' -print0 | sort -z | xargs -0 sha256sum)
} > "${WORK_DIR}/manifest.txt"
log " OK"
# --- Empaquetage final ---
log "Empaquetage du bundle dans ${BUNDLE_FILE}..."
tar -czf "${BUNDLE_FILE}" -C "${DEST_DIR}" "${BUNDLE_NAME}"
BUNDLE_SIZE="$(du -h "${BUNDLE_FILE}" | cut -f1)"
BUNDLE_SHA="$(sha256sum "${BUNDLE_FILE}" | cut -d' ' -f1)"
log "=== Export termine ==="
log "Bundle : ${BUNDLE_FILE}"
log "Taille : ${BUNDLE_SIZE}"
log "SHA-256 : ${BUNDLE_SHA}"
log
log "Pour transferer vers le nouveau serveur:"
log " scp '${BUNDLE_FILE}' user@nouveau-serveur:/var/www/e-ticket/"
log "Puis sur le nouveau serveur:"
log " ./restore.sh '${BUNDLE_NAME}.tar.gz'"