#!/bin/bash
# =============================================================================
# Script Name: docker_pgsql_backup.sh
# Version: 1.0
# Author: Andreas Fleckl
# Description: This script performs backups of PostgreSQL databases running in 
#              Docker containers. The backups are categorized into daily, 
#              weekly, and monthly directories, and old backups are deleted 
#              based on their age.
# =============================================================================

# Basisverzeichnis für die Backups
BACKUP_BASE_DIR="/var/backups/docker-pgsql"
# Datumsformat für den Dateinamen
DATE=$(date +%Y%m%d_%H%M)
# Sicherstellen, dass die Backup-Verzeichnisse existieren
mkdir -p "$BACKUP_BASE_DIR/daily"
mkdir -p "$BACKUP_BASE_DIR/weekly"
mkdir -p "$BACKUP_BASE_DIR/monthly"
# Datei, die die Liste der Docker-Containernamen, Benutzer und Passwörter enthält
CONTAINER_LIST="/root/scripts/container_pgsql_backup_hostlist.txt"
# Log-Datei
LOG_FILE="/var/log/docker_pgsql_backup.log"

# Funktion zum Versenden von E-Mail-Benachrichtigungen (optional)
send_email() {
	local SUBJECT=$1
	local MESSAGE=$2
	echo "$MESSAGE" | mail -s "$SUBJECT" your-email@example.com
}

# Funktion, um das Zielverzeichnis basierend auf dem Datum zu bestimmen
get_backup_dir() {
	local DAY_OF_MONTH=$(date +%d)
	local DAY_OF_WEEK=$(date +%u)
	if [ "$DAY_OF_MONTH" -eq 1 ]; then
		echo "$BACKUP_BASE_DIR/monthly"
	elif [ "$DAY_OF_WEEK" -eq 7 ]; then
		echo "$BACKUP_BASE_DIR/weekly"
	else
		echo "$BACKUP_BASE_DIR/daily"
	fi
}

# Funktion zum Löschen alter Backups
delete_old_backups() {
	# Löschen von täglichen Backups, die älter als 7 Tage sind
	find "$BACKUP_BASE_DIR/daily" -type f -mtime +7 -name '*.zst' -exec rm {} \;
	echo "Deleted backups older than 7 days from daily directory." | tee -a "$LOG_FILE"
    
	# Löschen von wöchentlichen Backups, die älter als 30 Tage sind
	find "$BACKUP_BASE_DIR/weekly" -type f -mtime +30 -name '*.zst' -exec rm {} \;
	echo "Deleted backups older than 30 days from weekly directory." | tee -a "$LOG_FILE"
}

# Start des Backups
echo "Backup process started at $(date)" | tee -a "$LOG_FILE"

# Alte Backups löschen
delete_old_backups

# Durch jede Zeile in der Containerliste durchlaufen
while IFS= read -r LINE
do
	CONTAINER_NAME=$(echo $LINE | cut -d ' ' -f 1)
	DB_USER=$(echo $LINE | cut -d ' ' -f 2)
	DB_PASSWORD=$(echo $LINE | cut -d ' ' -f 3)
	echo "Starting backup for container: $CONTAINER_NAME with user: $DB_USER" | tee -a "$LOG_FILE"
	
	# Setzen der Umgebungsvariable für das Passwort
	export PGPASSWORD="$DB_PASSWORD"
	
	# Bestimme das Zielverzeichnis
	BACKUP_DIR=$(get_backup_dir)
    
	# pg_dumpall ausführen und mit zstd komprimieren
	if docker exec "$CONTAINER_NAME" pg_dumpall -U "$DB_USER" | zstd > "${BACKUP_DIR}/${CONTAINER_NAME}_backup_${DATE}.sql.zst"; then
		echo "Backup successful for container: $CONTAINER_NAME" | tee -a "$LOG_FILE"
	else
		echo "Backup failed for container: $CONTAINER_NAME" | tee -a "$LOG_FILE"
		send_email "Backup failed for container: $CONTAINER_NAME" "The backup for container $CONTAINER_NAME failed at $(date). Please check the logs for details."
	fi
	
	# Umgebungsvariable löschen
	unset PGPASSWORD
done < "$CONTAINER_LIST"

echo "Backup process completed at $(date)" | tee -a "$LOG_FILE"
  1. ln -s /root/scripts/docker-pgsql-backup.sh /etc/cron.daily/docker-pgsql-backup