diff --git a/scripts/backup.sh b/scripts/backup.sh new file mode 100644 index 0000000..b3b01ab --- /dev/null +++ b/scripts/backup.sh @@ -0,0 +1,89 @@ +#!/usr/bin/env bash +# ===================================================================== +# WebGIS Database Backup Script +# Location: /opt/webgis-lohne/scripts/backup.sh (on server) +# Purpose: Creates compressed pg_dump backups with daily/weekly/monthly +# rotation. Intended to be run via cron. +# ===================================================================== + +set -euo pipefail + +# --------------------------------------------------------------------- +# Configuration +# --------------------------------------------------------------------- +DB_HOST="localhost" +DB_PORT="5432" +DB_NAME="webgis-db" +DB_USER="webgis-db-admin" + +BACKUP_ROOT="/var/backups/webgis" +BACKUP_DIR_DAILY="${BACKUP_ROOT}/daily" +BACKUP_DIR_WEEKLY="${BACKUP_ROOT}/weekly" +BACKUP_DIR_MONTHLY="${BACKUP_ROOT}/monthly" + +# Retention Periods (in days) +KEEP_DAILY=7 +KEEP_WEEKLY=28 +KEEP_MONTHLY=365 + +# Password is read from a protected file (see setup instructions). +# pg_dump honors the PGPASSFILE environment variable. +export PGPASSFILE="/root/.pgpass_webgis" + + +# --------------------------------------------------------------------- +# Preparation +# --------------------------------------------------------------------- +TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S") +DAY_OF_WEEK=$(date +"%u") # 1=Monday ... 7=Sunday +DAY_OF_MONTH=$(date +"%d") + +mkdir -p "${BACKUP_DIR_DAILY}" "${BACKUP_DIR_WEEKLY}" "${BACKUP_DIR_MONTHLY}" + + +# --------------------------------------------------------------------- +# Create Daily Backup (Custom-Format, compressed) +# --------------------------------------------------------------------- +DAILY_FILE="${BACKUP_DIR_DAILY}/webgis_${TIMESTAMP}.dump" + +echo "[$(date)] Starting daily backup -> ${DAILY_FILE}" + +pg_dump \ + --host="${DB_HOST}" \ + --port="${DB_PORT}" \ + --username="${DB_USER}" \ + --format=custom \ + --compress=9 \ + --file="${DAILY_FILE}" \ + "${DB_NAME}" + +echo "[$(date)] Daily backup complete." + + +# --------------------------------------------------------------------- +# Promote to Weekly Backup on Sundays +# --------------------------------------------------------------------- +if [[ "${DAY_OF_WEEK}" == "7" ]]; then + cp "${DAILY_FILE}" "${BACKUP_DIR_WEEKLY}/webgis_${TIMESTAMP}.dump" + echo "[$(date)] Promoted to weekly backup." +fi + + +# --------------------------------------------------------------------- +# Promote to Monthly Backup on the First of the Month +# --------------------------------------------------------------------- +if [[ "${DAY_OF_MONTH}" == "01" ]]; then + cp "${DAILY_FILE}" "${BACKUP_DIR_MONTHLY}/webgis_${TIMESTAMP}.dump" + echo "[$(date)] Promoted to monthly backup." +fi + + +# --------------------------------------------------------------------- +# Rotation: Delete Backups Older than Retention Period +# --------------------------------------------------------------------- +find "${BACKUP_DIR_DAILY}" -name "*.dump" -mtime +${KEEP_DAILY} -delete +find "${BACKUP_DIR_WEEKLY}" -name "*.dump" -mtime +${KEEP_WEEKLY} -delete +find "${BACKUP_DIR_MONTHLY}" -name "*.dump" -mtime +${KEEP_MONTHLY} -delete + + +echo "[$(date)] Backup rotation complete." \ No newline at end of file