Implement PostgreSQL upgrade and rollback scripts, update docker-compose for PostgreSQL version 17.5, and enhance .gitignore to include backup files. Add README for upgrade instructions.

This commit is contained in:
Yuri-Lima
2025-08-31 12:11:50 +02:00
parent 9b841b21d9
commit 16c737c816
7 changed files with 160601 additions and 1 deletions

115
rollback_postgres_upgrade.sh Executable file
View File

@@ -0,0 +1,115 @@
#!/usr/bin/env bash
set -euo pipefail
COMPOSE=./docker-compose.yaml
SERVICE=postgres
DATA_DIR=./database
ROLLBACK_TIMESTAMP=$(date +%Y%m%d_%H%M%S)
echo "🧪 Validating docker-compose config..."
docker compose -f "$COMPOSE" config > /dev/null || {
echo "❌ docker-compose config failed. Restore aborted."
exit 1
}
# Extract current Postgres image
CURRENT_IMG=$(docker compose -f "$COMPOSE" config | grep "image:" | grep "$SERVICE" | awk '{print $2}' || true)
if [[ -z "$CURRENT_IMG" ]]; then
echo "❌ Could not detect current image for service '$SERVICE'."
exit 1
fi
CURRENT_TAG=$(basename "$CURRENT_IMG")
CURRENT_VERSION=$(echo "$CURRENT_TAG" | cut -d'-' -f1) # e.g., 17.5
# Detect appropriate backup folder
BACKUP_CANDIDATES=($(ls -td ./database_backup_* 2>/dev/null || true))
if [[ ${#BACKUP_CANDIDATES[@]} -eq 0 ]]; then
echo "❌ No backup directory found. Cannot determine previous version."
echo " Available folders:"
ls -1d ./database_backup_* || true
exit 1
elif [[ ${#BACKUP_CANDIDATES[@]} -eq 1 ]]; then
SELECTED_BACKUP="${BACKUP_CANDIDATES[0]}"
echo " Only one backup found. Using: ${SELECTED_BACKUP}"
else
SELECTED_BACKUP="${BACKUP_CANDIDATES[1]}"
echo " Multiple backups found. Using second latest: ${SELECTED_BACKUP}"
fi
# Extract version from selected backup folder
OLD_TAG=$(basename "$SELECTED_BACKUP" | sed -E 's/database_backup_(([^_]+)-alpine).*/\1/')
OLD_IMG="postgres:${OLD_TAG}"
DELETED_UPGRADE_DIR=./database_upgraded_${CURRENT_VERSION}_${ROLLBACK_TIMESTAMP}
echo "⏪ Initiating rollback from Postgres ${CURRENT_TAG} to ${OLD_IMG}..."
# Step 1: Confirm backup exists
if [ ! -d "$SELECTED_BACKUP" ]; then
echo "❌ Backup folder '${SELECTED_BACKUP}' not found. Aborting."
exit 1
fi
# Step 2: Stop services
echo "🛑 Stopping running services..."
docker compose -f "$COMPOSE" down
# Step 3: Archive current (possibly broken) database
echo "📦 Archiving current database directory as '${DELETED_UPGRADE_DIR}'..."
mv "$DATA_DIR" "$DELETED_UPGRADE_DIR"
# Step 4: Restore previous version
echo "♻️ Restoring from backup folder '${SELECTED_BACKUP}'..."
cp -a "$SELECTED_BACKUP" "$DATA_DIR"
# Step 5: Restore image tag in docker-compose.yaml
echo "🔁 Reverting docker-compose image tag to Postgres ${OLD_IMG}..."
update_image_tag() {
local svc="$1"
local file="$2"
local target_tag="$3"
echo "🔁 Reverting docker-compose image tag for service '$svc' to Postgres: ${target_tag}..."
# Use awk to scope updates within the service definition only
awk -v service="$svc" -v new_tag="$target_tag" '
BEGIN { in_service = 0 }
/^[ ]{2}[a-zA-Z0-9_-]+:/ {
in_service = ($1 == service ":") ? 1 : 0
}
in_service && /^\s*image:/ {
sub(/postgres:[^"'"'"']+/, "postgres:" new_tag)
}
{ print }
' "$file" > "${file}.tmp" && mv "${file}.tmp" "$file"
}
update_image_tag "$SERVICE" "$COMPOSE" "$OLD_TAG"
# Step 6: Restart Postgres
echo "🚀 Starting Postgres service with restored image..."
docker compose -f "$COMPOSE" up -d "$SERVICE"
# Step 7: Final messages
echo "✅ Rollback complete!"
echo "🗃️ PostgreSQL downgraded to '${OLD_IMG}' and data restored from '${SELECTED_BACKUP}'."
echo "📦 The faulty upgrade has been archived in '${DELETED_UPGRADE_DIR}'."
echo " - To clean: rm -rf ${DELETED_UPGRADE_DIR}"
echo " - To verify: docker compose logs -f $SERVICE"
# Step 8: Restart full application
echo "🔄 Pulling latest images..."
if ! docker compose pull; then
echo "❌ Failed to pull images. Aborting."
exit 1
fi
echo "🔄 Starting full application stack..."
if ! docker compose up -d --force-recreate; then
echo "❌ Failed to start application stack. Please check logs."
exit 1
fi
echo "✅ Deployment completed successfully."