91 lines
2.4 KiB
Bash
91 lines
2.4 KiB
Bash
#!/usr/bin/env bash
|
|
#
|
|
# Create a compressed PostgreSQL backup and remove old backup files.
|
|
#
|
|
# Required environment variables:
|
|
# PGHOST PostgreSQL host.
|
|
# PGUSER PostgreSQL user.
|
|
# PGPASSWORD PostgreSQL password.
|
|
# PGDATABASE Database name to back up.
|
|
#
|
|
# Usage:
|
|
# PGHOST=localhost PGUSER=app PGPASSWORD=secret PGDATABASE=appdb \
|
|
# bash postgres_backup.sh --destination /backups/postgres
|
|
#
|
|
# Options:
|
|
# --destination DIR Backup directory. Default: ./backups
|
|
# --retention-days N Delete backups older than N days. Default: 14.
|
|
# --help Show this help message.
|
|
|
|
set -Eeuo pipefail
|
|
|
|
destination="./backups"
|
|
retention_days="14"
|
|
|
|
usage() {
|
|
sed -n '2,24p' "$0" | sed 's/^# \{0,1\}//'
|
|
}
|
|
|
|
log() {
|
|
printf '[%s] %s\n' "$(date -Is)" "$*"
|
|
}
|
|
|
|
require_env() {
|
|
local name="$1"
|
|
if [[ -z "${!name:-}" ]]; then
|
|
printf 'ERROR: required environment variable is missing: %s\n' "$name" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
while [[ "$#" -gt 0 ]]; do
|
|
case "$1" in
|
|
--destination)
|
|
destination="${2:-}"
|
|
[[ -n "$destination" ]] || { printf 'ERROR: --destination requires a directory.\n' >&2; exit 1; }
|
|
shift 2
|
|
;;
|
|
--retention-days)
|
|
retention_days="${2:-}"
|
|
[[ "$retention_days" =~ ^[0-9]+$ ]] || { printf 'ERROR: retention must be a positive integer.\n' >&2; exit 1; }
|
|
shift 2
|
|
;;
|
|
--help|-h)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
printf 'ERROR: unknown option: %s\n' "$1" >&2
|
|
usage >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
command -v pg_dump >/dev/null 2>&1 || { printf 'ERROR: pg_dump command not found.\n' >&2; exit 1; }
|
|
command -v gzip >/dev/null 2>&1 || { printf 'ERROR: gzip command not found.\n' >&2; exit 1; }
|
|
|
|
require_env PGHOST
|
|
require_env PGUSER
|
|
require_env PGPASSWORD
|
|
require_env PGDATABASE
|
|
|
|
mkdir -p "$destination"
|
|
|
|
timestamp="$(date +%Y%m%d-%H%M%S)"
|
|
backup_file="${destination}/${PGDATABASE}-${timestamp}.sql.gz"
|
|
|
|
log "Starting PostgreSQL backup for database '${PGDATABASE}'."
|
|
pg_dump --format=plain --no-owner --no-privileges "$PGDATABASE" | gzip -9 > "$backup_file"
|
|
|
|
if [[ ! -s "$backup_file" ]]; then
|
|
printf 'ERROR: backup file was not created or is empty: %s\n' "$backup_file" >&2
|
|
exit 1
|
|
fi
|
|
|
|
log "Backup created: ${backup_file}"
|
|
log "Removing backups older than ${retention_days} days from ${destination}."
|
|
find "$destination" -type f -name "${PGDATABASE}-*.sql.gz" -mtime "+${retention_days}" -print -delete
|
|
log "Backup job completed successfully."
|
|
|