mirror of
https://github.com/complexcaresolutions/cms.c2sgmbh.git
synced 2026-03-17 16:14:12 +00:00
- Add backup-db.sh for daily automated backups via cron - Add restore-db.sh for interactive database restoration - Add setup-backup.sh for easy setup on new servers - Support local and S3 (Hetzner Object Storage) backup locations - 30-day retention with automatic cleanup - Credentials stored securely in ~/.pgpass and ~/.s3cfg - Comprehensive documentation with disaster recovery checklist 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
293 lines
7.5 KiB
Bash
Executable file
293 lines
7.5 KiB
Bash
Executable file
#!/bin/bash
|
|
#
|
|
# Payload CMS - Backup-System Setup
|
|
# Richtet das automatische Backup-System auf einem neuen Server ein.
|
|
#
|
|
# Verwendung:
|
|
# ./setup-backup.sh
|
|
#
|
|
# Voraussetzungen:
|
|
# - PostgreSQL-Client (psql, pg_dump) installiert
|
|
# - Zugriff auf die Datenbank
|
|
#
|
|
|
|
set -euo pipefail
|
|
|
|
# ============================================================================
|
|
# Konfiguration
|
|
# ============================================================================
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
BACKUP_DIR="/home/payload/backups/postgres"
|
|
LOG_DIR="/home/payload/logs"
|
|
|
|
# ============================================================================
|
|
# Funktionen
|
|
# ============================================================================
|
|
|
|
print_header() {
|
|
echo ""
|
|
echo "=============================================="
|
|
echo " Payload CMS - Backup-System Setup"
|
|
echo "=============================================="
|
|
echo ""
|
|
}
|
|
|
|
print_step() {
|
|
echo "[$(date '+%H:%M:%S')] $1"
|
|
}
|
|
|
|
print_success() {
|
|
echo "[✓] $1"
|
|
}
|
|
|
|
print_error() {
|
|
echo "[✗] ERROR: $1" >&2
|
|
}
|
|
|
|
check_prerequisites() {
|
|
print_step "Prüfe Voraussetzungen..."
|
|
|
|
if ! command -v psql &> /dev/null; then
|
|
print_error "psql nicht gefunden. Installiere mit: apt install postgresql-client"
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v pg_dump &> /dev/null; then
|
|
print_error "pg_dump nicht gefunden. Installiere mit: apt install postgresql-client"
|
|
exit 1
|
|
fi
|
|
|
|
print_success "PostgreSQL-Client verfügbar"
|
|
}
|
|
|
|
setup_directories() {
|
|
print_step "Erstelle Verzeichnisse..."
|
|
|
|
mkdir -p "$BACKUP_DIR"
|
|
mkdir -p "$LOG_DIR"
|
|
|
|
print_success "Verzeichnisse erstellt"
|
|
}
|
|
|
|
setup_pgpass() {
|
|
local pgpass_file="$HOME/.pgpass"
|
|
|
|
print_step "Konfiguriere PostgreSQL-Authentifizierung..."
|
|
|
|
if [[ -f "$pgpass_file" ]]; then
|
|
echo " .pgpass existiert bereits."
|
|
read -p " Überschreiben? [y/N] " -n 1 -r
|
|
echo
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
print_success ".pgpass beibehalten"
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
echo " PostgreSQL-Verbindungsdaten eingeben:"
|
|
read -p " Host [10.10.181.101]: " db_host
|
|
db_host=${db_host:-10.10.181.101}
|
|
|
|
read -p " Port [5432]: " db_port
|
|
db_port=${db_port:-5432}
|
|
|
|
read -p " Datenbank [payload_db]: " db_name
|
|
db_name=${db_name:-payload_db}
|
|
|
|
read -p " Benutzer [payload]: " db_user
|
|
db_user=${db_user:-payload}
|
|
|
|
read -sp " Passwort: " db_pass
|
|
echo ""
|
|
|
|
if [[ -z "$db_pass" ]]; then
|
|
print_error "Passwort darf nicht leer sein"
|
|
exit 1
|
|
fi
|
|
|
|
echo "${db_host}:${db_port}:${db_name}:${db_user}:${db_pass}" > "$pgpass_file"
|
|
chmod 600 "$pgpass_file"
|
|
|
|
print_success ".pgpass erstellt (chmod 600)"
|
|
|
|
# Test connection
|
|
print_step "Teste Datenbankverbindung..."
|
|
if psql -h "$db_host" -p "$db_port" -U "$db_user" -d "$db_name" -c "SELECT 1" > /dev/null 2>&1; then
|
|
print_success "Datenbankverbindung erfolgreich"
|
|
else
|
|
print_error "Datenbankverbindung fehlgeschlagen"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
setup_s3() {
|
|
local s3cfg_file="$HOME/.s3cfg"
|
|
|
|
print_step "Konfiguriere S3 Offsite-Backup..."
|
|
|
|
read -p " S3 Offsite-Backup aktivieren? [Y/n] " -n 1 -r
|
|
echo
|
|
if [[ $REPLY =~ ^[Nn]$ ]]; then
|
|
print_success "S3-Backup übersprungen"
|
|
return 0
|
|
fi
|
|
|
|
# Check if s3cmd is installed
|
|
if ! command -v s3cmd &> /dev/null; then
|
|
echo " s3cmd nicht gefunden. Installiere..."
|
|
if command -v apt &> /dev/null; then
|
|
sudo apt update && sudo apt install -y s3cmd
|
|
else
|
|
print_error "Bitte s3cmd manuell installieren"
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
if [[ -f "$s3cfg_file" ]]; then
|
|
echo " .s3cfg existiert bereits."
|
|
read -p " Überschreiben? [y/N] " -n 1 -r
|
|
echo
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
print_success ".s3cfg beibehalten"
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
echo " S3-Verbindungsdaten eingeben:"
|
|
read -p " S3 Host (z.B. fsn1.your-objectstorage.com): " s3_host
|
|
|
|
if [[ -z "$s3_host" ]]; then
|
|
print_error "S3 Host darf nicht leer sein"
|
|
return 1
|
|
fi
|
|
|
|
read -p " Access Key: " s3_access_key
|
|
read -sp " Secret Key: " s3_secret_key
|
|
echo ""
|
|
|
|
if [[ -z "$s3_access_key" || -z "$s3_secret_key" ]]; then
|
|
print_error "Access Key und Secret Key dürfen nicht leer sein"
|
|
return 1
|
|
fi
|
|
|
|
cat > "$s3cfg_file" << EOF
|
|
[default]
|
|
access_key = ${s3_access_key}
|
|
secret_key = ${s3_secret_key}
|
|
host_base = ${s3_host}
|
|
host_bucket = %(bucket)s.${s3_host}
|
|
use_https = True
|
|
signature_v2 = False
|
|
EOF
|
|
chmod 600 "$s3cfg_file"
|
|
|
|
print_success ".s3cfg erstellt (chmod 600)"
|
|
|
|
# Test S3 connection
|
|
print_step "Teste S3-Verbindung..."
|
|
if s3cmd ls > /dev/null 2>&1; then
|
|
print_success "S3-Verbindung erfolgreich"
|
|
s3cmd ls
|
|
else
|
|
print_error "S3-Verbindung fehlgeschlagen"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
install_backup_script() {
|
|
print_step "Installiere Backup-Skript..."
|
|
|
|
local source_script="${SCRIPT_DIR}/backup-db.sh"
|
|
local target_script="${BACKUP_DIR}/backup-db.sh"
|
|
|
|
if [[ ! -f "$source_script" ]]; then
|
|
print_error "Backup-Skript nicht gefunden: $source_script"
|
|
exit 1
|
|
fi
|
|
|
|
cp "$source_script" "$target_script"
|
|
chmod +x "$target_script"
|
|
|
|
print_success "Backup-Skript installiert: $target_script"
|
|
}
|
|
|
|
setup_cron() {
|
|
print_step "Konfiguriere Cron-Job..."
|
|
|
|
local cron_entry="0 3 * * * ${BACKUP_DIR}/backup-db.sh >> ${LOG_DIR}/backup-cron.log 2>&1"
|
|
|
|
# Check if cron entry already exists
|
|
if crontab -l 2>/dev/null | grep -q "backup-db.sh"; then
|
|
echo " Cron-Job existiert bereits."
|
|
read -p " Überschreiben? [y/N] " -n 1 -r
|
|
echo
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
print_success "Cron-Job beibehalten"
|
|
return 0
|
|
fi
|
|
# Remove existing entry
|
|
crontab -l 2>/dev/null | grep -v "backup-db.sh" | crontab -
|
|
fi
|
|
|
|
# Add new cron entry
|
|
(crontab -l 2>/dev/null; echo "# Payload CMS - Tägliches PostgreSQL Backup"; echo "$cron_entry") | crontab -
|
|
|
|
print_success "Cron-Job eingerichtet (täglich um 03:00 Uhr)"
|
|
}
|
|
|
|
test_backup() {
|
|
print_step "Teste Backup..."
|
|
|
|
read -p " Test-Backup jetzt ausführen? [Y/n] " -n 1 -r
|
|
echo
|
|
if [[ $REPLY =~ ^[Nn]$ ]]; then
|
|
print_success "Test übersprungen"
|
|
return 0
|
|
fi
|
|
|
|
if "${BACKUP_DIR}/backup-db.sh" --verbose; then
|
|
print_success "Test-Backup erfolgreich"
|
|
else
|
|
print_error "Test-Backup fehlgeschlagen"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
print_summary() {
|
|
echo ""
|
|
echo "=============================================="
|
|
echo " Setup abgeschlossen!"
|
|
echo "=============================================="
|
|
echo ""
|
|
echo " Backup-Skript: ${BACKUP_DIR}/backup-db.sh"
|
|
echo " Lokale Backups: ${BACKUP_DIR}/"
|
|
echo " Log-Dateien: ${BACKUP_DIR}/backup.log"
|
|
echo " ${LOG_DIR}/backup-cron.log"
|
|
echo ""
|
|
echo " Cron-Job: Täglich um 03:00 Uhr"
|
|
echo ""
|
|
echo " Manuelle Ausführung:"
|
|
echo " ${BACKUP_DIR}/backup-db.sh --verbose"
|
|
echo ""
|
|
}
|
|
|
|
# ============================================================================
|
|
# Hauptprogramm
|
|
# ============================================================================
|
|
|
|
main() {
|
|
print_header
|
|
check_prerequisites
|
|
setup_directories
|
|
setup_pgpass
|
|
setup_s3
|
|
install_backup_script
|
|
setup_cron
|
|
test_backup
|
|
print_summary
|
|
}
|
|
|
|
main "$@"
|