mirror of
https://github.com/prodrigestivill/docker-postgres-backup-local.git
synced 2026-05-31 08:37:58 +00:00
265 lines
6.0 KiB
Bash
Executable File
265 lines
6.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# Import variables from environment
|
|
export PGHOST="${POSTGRES_HOST}"
|
|
export PGPORT="${POSTGRES_PORT}"
|
|
KEEP_MINS=${BACKUP_KEEP_MINS}
|
|
KEEP_DAYS=${BACKUP_KEEP_DAYS}
|
|
KEEP_WEEKS=`expr $((${BACKUP_KEEP_WEEKS} * 7))`
|
|
KEEP_MONTHS=`expr $((${BACKUP_KEEP_MONTHS} * 31))`
|
|
|
|
setup () {
|
|
|
|
set -Eeo pipefail
|
|
|
|
if [ "${POSTGRES_DB}" = "**None**" -a "${POSTGRES_DB_FILE}" = "**None**" ]; then
|
|
echo "You need to set the POSTGRES_DB or POSTGRES_DB_FILE environment variable."
|
|
exit 1
|
|
fi
|
|
|
|
if [ "${POSTGRES_HOST}" = "**None**" ]; then
|
|
if [ -n "${POSTGRES_PORT_5432_TCP_ADDR}" ]; then
|
|
POSTGRES_HOST=${POSTGRES_PORT_5432_TCP_ADDR}
|
|
POSTGRES_PORT=${POSTGRES_PORT_5432_TCP_PORT}
|
|
else
|
|
echo "You need to set the POSTGRES_HOST environment variable."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
if [ "${POSTGRES_USER}" = "**None**" -a "${POSTGRES_USER_FILE}" = "**None**" ]; then
|
|
echo "You need to set the POSTGRES_USER or POSTGRES_USER_FILE environment variable."
|
|
exit 1
|
|
fi
|
|
|
|
if [ "${POSTGRES_PASSWORD}" = "**None**" -a "${POSTGRES_PASSWORD_FILE}" = "**None**" -a "${POSTGRES_PASSFILE_STORE}" = "**None**" ]; then
|
|
echo "You need to set the POSTGRES_PASSWORD or POSTGRES_PASSWORD_FILE or POSTGRES_PASSFILE_STORE environment variable or link to a container named POSTGRES."
|
|
exit 1
|
|
fi
|
|
|
|
#Process vars
|
|
if [ "${POSTGRES_DB_FILE}" = "**None**" ]; then
|
|
POSTGRES_DBS=$(echo "${POSTGRES_DB}" | tr , " ")
|
|
elif [ -r "${POSTGRES_DB_FILE}" ]; then
|
|
POSTGRES_DBS=$(cat "${POSTGRES_DB_FILE}")
|
|
else
|
|
echo "Missing POSTGRES_DB_FILE file."
|
|
exit 1
|
|
fi
|
|
if [ "${POSTGRES_USER_FILE}" = "**None**" ]; then
|
|
export PGUSER="${POSTGRES_USER}"
|
|
elif [ -r "${POSTGRES_USER_FILE}" ]; then
|
|
export PGUSER=$(cat "${POSTGRES_USER_FILE}")
|
|
else
|
|
echo "Missing POSTGRES_USER_FILE file."
|
|
exit 1
|
|
fi
|
|
if [ "${POSTGRES_PASSWORD_FILE}" = "**None**" -a "${POSTGRES_PASSFILE_STORE}" = "**None**" ]; then
|
|
export PGPASSWORD="${POSTGRES_PASSWORD}"
|
|
elif [ -r "${POSTGRES_PASSWORD_FILE}" ]; then
|
|
export PGPASSWORD=$(cat "${POSTGRES_PASSWORD_FILE}")
|
|
elif [ -r "${POSTGRES_PASSFILE_STORE}" ]; then
|
|
export PGPASSFILE="${POSTGRES_PASSFILE_STORE}"
|
|
else
|
|
echo "Missing POSTGRES_PASSWORD_FILE or POSTGRES_PASSFILE_STORE file."
|
|
exit 1
|
|
fi
|
|
|
|
FREQUENCY=( daily weekly monthly )
|
|
|
|
for f in ${FREQUENCY[@]}
|
|
do
|
|
|
|
mkdir -p "${BACKUP_DIR}/${f}/"
|
|
|
|
done
|
|
|
|
MONTH_DAY=`date +%d`
|
|
WEEK_DAY=`date +%A`
|
|
|
|
}
|
|
|
|
#Create Backups
|
|
create_backups () {
|
|
|
|
for DB in ${POSTGRES_DBS}
|
|
do
|
|
|
|
FILE="${BACKUP_DIR}/daily/${DB}-`date +%Y%m%d`${BACKUP_SUFFIX}"
|
|
|
|
create_dump
|
|
|
|
if [ "${BACKUP_MONTH_DAY}" = "${MONTH_DAY}" ]
|
|
then
|
|
|
|
create_hardlinks "${FILE}" "monthly"
|
|
|
|
elif [ "${BACKUP_WEEK_DAY}" = "${WEEK_DAY}" ]
|
|
then
|
|
|
|
create_hardlinks "${FILE}" "weekly"
|
|
|
|
fi
|
|
|
|
echo "SQL backup created successfully"
|
|
|
|
done
|
|
|
|
}
|
|
|
|
# Create dump of postgres database
|
|
create_dump () {
|
|
|
|
if [ "${POSTGRES_CLUSTER}" = "TRUE" ]; then
|
|
echo "Creating cluster dump of ${DB} database from ${POSTGRES_HOST}..."
|
|
pg_dumpall -l "${DB}" ${POSTGRES_EXTRA_OPTS} | gzip > "${FILE}"
|
|
else
|
|
echo "Creating dump of ${DB} database from ${POSTGRES_HOST}..."
|
|
pg_dump -d "${DB}" -f "${FILE}" ${POSTGRES_EXTRA_OPTS}
|
|
fi
|
|
|
|
}
|
|
|
|
# Create hardlinks from daily backup to monthly and weekly backups
|
|
create_hardlinks () {
|
|
|
|
SRC=$1
|
|
INCREMENT=$2
|
|
|
|
if [ "${INCREMENT}" = "weekly" ]
|
|
then
|
|
|
|
echo "Creating Weekly Backup of ${DB} database from ${POSTGRES_HOST}..."
|
|
FILENAME="${DB}-`date +%G%V`${BACKUP_SUFFIX}"
|
|
|
|
elif [ "${INCREMENT}" = "monthly"]
|
|
then
|
|
|
|
echo "Creating Monthly Backup of ${DB} database from ${POSTGRES_HOST}..."
|
|
FILENAME="${DB}-`date +%Y%m`${BACKUP_SUFFIX}"
|
|
|
|
fi
|
|
|
|
DEST="${BACKUP_DIR}/${INCREMENT}/${FILENAME}"
|
|
|
|
#Copy (hardlink) for each entry
|
|
if [ -d "${SRC}" ]
|
|
then
|
|
ln -f "${SRC}/"* "${DEST}/"
|
|
else
|
|
ln -vf "${SRC}" "${DEST}"
|
|
fi
|
|
# Update latest symlinks
|
|
ln -svf "${DEST}" "${BACKUP_DIR}/${INCREMENT}/${DB}-latest"
|
|
|
|
}
|
|
|
|
#Clean up old backups
|
|
cleanup_backups () {
|
|
|
|
for folder in "${FREQUENCY[@]}"
|
|
do
|
|
if [ $folder == "weekly" ]
|
|
then
|
|
KEEP=$BACKUP_KEEP_WEEKS
|
|
DELETE=$BACKUP_DELETE_WEEKS
|
|
elif [ $folder == 'monthly' ]
|
|
then
|
|
KEEP=$BACKUP_KEEP_MONTHS
|
|
DELETE=$BACKUP_DELETE_MONTHS
|
|
elif [ $folder == 'daily' ]
|
|
then
|
|
KEEP=$BACKUP_KEEP_DAYS
|
|
DELETE=$BACKUP_DELETE_DAYS
|
|
fi
|
|
|
|
for DB in ${POSTGRES_DBS}
|
|
do
|
|
|
|
#Clean old files
|
|
local all=( `find "${BACKUP_DIR}/${folder}" -maxdepth 1 -name "${DB}-*"` )
|
|
local files=()
|
|
|
|
if [ $KEEP -gt 0 ]
|
|
then
|
|
|
|
echo "Cleaning older files in ${folder} for ${DB} database from ${POSTGRES_HOST}..."
|
|
local files=( `find "${BACKUP_DIR}/${folder}" -maxdepth 1 -mtime "+$((${KEEP}-1))" -name "${DB}-*"` )
|
|
local files=( `printf "%s\n" "${files[@]}" | sort -t/ -k3` )
|
|
|
|
if [ $((${#all[@]}-${#files[@]})) -lt ${KEEP} ]
|
|
then
|
|
|
|
local number=$((${#all[@]}-${#files[@]}))
|
|
|
|
local files=("${files[@]:0:$number}")
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
if [ $((${#all[@]})) -lt ${KEEP} ]
|
|
then
|
|
|
|
echo "Only ${#all[@]} Backups exist for ${DB} and you want to keep $KEEP."
|
|
echo "If you have just started taking backups you may ignore this"
|
|
echo "Otherwise you may want to investigate why backups are not being taken"
|
|
|
|
elif $DELETE
|
|
then
|
|
for file in "${files[@]}"
|
|
do
|
|
|
|
echo "Deleting $file"
|
|
rm $file
|
|
|
|
done
|
|
else
|
|
for file in "${files[@]}"
|
|
do
|
|
|
|
echo "Dry Run: Delete $file"
|
|
|
|
done
|
|
fi
|
|
|
|
done
|
|
|
|
done
|
|
}
|
|
|
|
listCommands () {
|
|
|
|
echo "--create-backup -b Create Daily, Weekly and Monthly backups"
|
|
echo "--cleanup -c Cleanup old backups"
|
|
echo "--help -h List commands"
|
|
|
|
}
|
|
|
|
case $1 in
|
|
|
|
"--create-backup" | "-b")
|
|
|
|
setup
|
|
create_backups
|
|
;;
|
|
|
|
"--cleanup" | "-c")
|
|
|
|
setup
|
|
cleanup_backups
|
|
;;
|
|
|
|
"--help" | "-h")
|
|
|
|
listCommands
|
|
;;
|
|
|
|
*)
|
|
|
|
setup
|
|
create_backups
|
|
cleanup_backups
|
|
|
|
esac
|