|
| 1 | +#!/bin/bash |
| 2 | +# pg_backup_restore.sh |
| 3 | +# Backup and restore PostgreSQL databases using static credentials from a .env file |
| 4 | +# Backup will exclude ownership information |
| 5 | + |
| 6 | +set -e |
| 7 | + |
| 8 | +# Check for psql version 17 |
| 9 | +check_psql_version() { |
| 10 | + echo "🔧 Checking PostgreSQL client version..." |
| 11 | + |
| 12 | + if ! command -v psql >/dev/null 2>&1; then |
| 13 | + echo "❌ Error: PostgreSQL client (psql) is not installed." >&2 |
| 14 | + echo "💡 Please install PostgreSQL 17 client tools." >&2 |
| 15 | + exit 2 |
| 16 | + fi |
| 17 | + |
| 18 | + local version |
| 19 | + version=$(psql --version | awk '{print $3}') |
| 20 | + major_version=$(echo "$version" | cut -d. -f1) |
| 21 | + |
| 22 | + echo "📋 Found PostgreSQL client version: $version" |
| 23 | + |
| 24 | + if [ "$major_version" != "17" ]; then |
| 25 | + echo "❌ Error: PostgreSQL client version 17 is required. Found version $version." >&2 |
| 26 | + echo "💡 Please install PostgreSQL 17 client tools for compatibility." >&2 |
| 27 | + exit 3 |
| 28 | + fi |
| 29 | + |
| 30 | + echo "✅ PostgreSQL client version 17 verified!" |
| 31 | + echo "" |
| 32 | +} |
| 33 | + |
| 34 | +# Load environment variables from .env file in the same directory as the script |
| 35 | +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| 36 | +ENV_FILE="$SCRIPT_DIR/.env" |
| 37 | + |
| 38 | +echo "🗂️ Loading database configuration from .env file..." |
| 39 | + |
| 40 | +if [ -f "$ENV_FILE" ]; then |
| 41 | + echo "✓ Found .env file at: $ENV_FILE" |
| 42 | + set -a |
| 43 | + # shellcheck source=.env |
| 44 | + source "$ENV_FILE" |
| 45 | + set +a |
| 46 | + echo "✓ Environment variables loaded successfully" |
| 47 | + echo "" |
| 48 | +else |
| 49 | + echo "❌ Error: .env file not found at $ENV_FILE" >&2 |
| 50 | + echo "💡 Please create a .env file with the required database configuration." >&2 |
| 51 | + exit 4 |
| 52 | +fi |
| 53 | + |
| 54 | +# Validate required environment variables |
| 55 | +require_env_vars() { |
| 56 | + local missing=0 |
| 57 | + echo "🔍 Validating database configuration..." |
| 58 | + |
| 59 | + for var in DB_HOST DB_PORT DB_USER DB_PASSWORD DB_NAME; do |
| 60 | + if [ -z "${!var}" ]; then |
| 61 | + echo "❌ Error: $var is not set in .env file." >&2 |
| 62 | + missing=1 |
| 63 | + else |
| 64 | + if [ "$var" != "DB_PASSWORD" ]; then |
| 65 | + echo "✓ $var: ${!var}" |
| 66 | + else |
| 67 | + echo "✓ $var: [HIDDEN]" |
| 68 | + fi |
| 69 | + fi |
| 70 | + done |
| 71 | + |
| 72 | + if [ "$missing" -eq 1 ]; then |
| 73 | + echo "" |
| 74 | + echo "❌ Configuration validation failed! Please check your .env file." |
| 75 | + exit 5 |
| 76 | + fi |
| 77 | + |
| 78 | + echo "✅ Database configuration validated successfully!" |
| 79 | + echo "" |
| 80 | +} |
| 81 | + |
| 82 | +usage() { |
| 83 | + echo "" |
| 84 | + echo "PostgreSQL Backup & Restore Script" |
| 85 | + echo "----------------------------------" |
| 86 | + echo "Usage:" |
| 87 | + echo " $0 backup <output_file> # Create a backup of the database to <output_file>" |
| 88 | + echo " $0 restore <input_file> # Restore the database from <input_file>" |
| 89 | + echo "" |
| 90 | + echo "Environment:" |
| 91 | + echo " Reads DB credentials from .env file in the same directory as this script." |
| 92 | + echo " .env file must contain:" |
| 93 | + echo " DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME" |
| 94 | + echo "" |
| 95 | + echo "Examples:" |
| 96 | + echo " $0 backup backup.sql" |
| 97 | + echo " $0 restore backup.sql" |
| 98 | + echo "" |
| 99 | + exit 1 |
| 100 | +} |
| 101 | + |
| 102 | +run_backup() { |
| 103 | + local output_file="$1" |
| 104 | + echo "🔄 Starting database backup operation..." |
| 105 | + echo "📊 Database: $DB_NAME" |
| 106 | + echo "🖥️ Host: $DB_HOST:$DB_PORT" |
| 107 | + echo "👤 User: $DB_USER" |
| 108 | + echo "📁 Output file: $output_file" |
| 109 | + echo "" |
| 110 | + echo "⏳ Running pg_dump (this may take a while for large databases)..." |
| 111 | + |
| 112 | + PGPASSWORD="$DB_PASSWORD" pg_dump --host="$DB_HOST" --port="$DB_PORT" --username="$DB_USER" --no-owner --format=plain --file="$output_file" "$DB_NAME" |
| 113 | + |
| 114 | + if [ $? -eq 0 ]; then |
| 115 | + echo "✅ Backup completed successfully!" |
| 116 | + echo "📄 Backup file: $output_file" |
| 117 | + echo "📊 File size: $(du -h "$output_file" | cut -f1)" |
| 118 | + else |
| 119 | + echo "❌ Backup failed! Please check your database connection and permissions." >&2 |
| 120 | + exit 6 |
| 121 | + fi |
| 122 | +} |
| 123 | + |
| 124 | +run_restore() { |
| 125 | + local input_file="$1" |
| 126 | + |
| 127 | + # Check if input file exists |
| 128 | + if [ ! -f "$input_file" ]; then |
| 129 | + echo "❌ Error: Backup file '$input_file' does not exist!" >&2 |
| 130 | + exit 8 |
| 131 | + fi |
| 132 | + |
| 133 | + echo "🔄 Database restore operation" |
| 134 | + echo "📊 Target database: $DB_NAME" |
| 135 | + echo "🖥️ Host: $DB_HOST:$DB_PORT" |
| 136 | + echo "👤 User: $DB_USER" |
| 137 | + echo "📁 Source file: $input_file" |
| 138 | + echo "📊 File size: $(du -h "$input_file" | cut -f1)" |
| 139 | + echo "" |
| 140 | + echo "⚠️ WARNING: This will overwrite all data in the target database!" |
| 141 | + echo "" |
| 142 | + |
| 143 | + read -p "🤔 Are you sure you want to restore the database '$DB_NAME' from '$input_file'? [y/N]: " confirm |
| 144 | + if [[ "$confirm" =~ ^[Yy]$ ]]; then |
| 145 | + echo "" |
| 146 | + echo "⏳ Running database restore (this may take a while for large backups)..." |
| 147 | + |
| 148 | + PGPASSWORD="$DB_PASSWORD" psql --host="$DB_HOST" --port="$DB_PORT" --username="$DB_USER" --dbname="$DB_NAME" -f "$input_file" |
| 149 | + |
| 150 | + if [ $? -eq 0 ]; then |
| 151 | + echo "" |
| 152 | + echo "✅ Database restore completed successfully!" |
| 153 | + echo "📊 Database '$DB_NAME' has been restored from '$input_file'" |
| 154 | + else |
| 155 | + echo "" |
| 156 | + echo "❌ Restore failed! Please check the backup file format and database permissions." >&2 |
| 157 | + exit 7 |
| 158 | + fi |
| 159 | + else |
| 160 | + echo "" |
| 161 | + echo "🚫 Restore operation cancelled by user." |
| 162 | + exit 0 |
| 163 | + fi |
| 164 | +} |
| 165 | + |
| 166 | +if [ $# -lt 2 ]; then |
| 167 | + usage |
| 168 | +fi |
| 169 | + |
| 170 | +echo "🚀 PostgreSQL Backup & Restore Script Starting..." |
| 171 | +echo "" |
| 172 | + |
| 173 | +check_psql_version |
| 174 | +require_env_vars |
| 175 | + |
| 176 | +COMMAND="$1" |
| 177 | +FILE="$2" |
| 178 | + |
| 179 | +echo "📋 Operation requested: $COMMAND" |
| 180 | +echo "📁 Target file: $FILE" |
| 181 | +echo "" |
| 182 | + |
| 183 | +case "$COMMAND" in |
| 184 | + backup) |
| 185 | + run_backup "$FILE" |
| 186 | + ;; |
| 187 | + restore) |
| 188 | + run_restore "$FILE" |
| 189 | + ;; |
| 190 | + *) |
| 191 | + echo "❌ Error: Unknown command '$COMMAND'" >&2 |
| 192 | + usage |
| 193 | + ;; |
| 194 | +esac |
0 commit comments