forked from prodrigestivill/docker-postgres-backup-local
-
Notifications
You must be signed in to change notification settings - Fork 0
/
backup.sh
executable file
·145 lines (134 loc) · 5.59 KB
/
backup.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/env bash
set -Eeo pipefail
HOOKS_DIR="/hooks"
if [ -d "${HOOKS_DIR}" ]; then
on_error(){
run-parts -a "error" "${HOOKS_DIR}"
}
trap 'on_error' ERR
fi
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
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) + 1))`
KEEP_MONTHS=`expr $(((${BACKUP_KEEP_MONTHS} * 31) + 1))`
# Pre-backup hook
if [ -d "${HOOKS_DIR}" ]; then
run-parts -a "pre-backup" --exit-on-error "${HOOKS_DIR}"
fi
#Initialize dirs
mkdir -p "${BACKUP_DIR}/last/" "${BACKUP_DIR}/daily/" "${BACKUP_DIR}/weekly/" "${BACKUP_DIR}/monthly/"
#Loop all databases
for DB in ${POSTGRES_DBS}; do
#Initialize filename vers
LAST_FILENAME="${DB}-`date +%Y%m%d-%H%M%S`${BACKUP_SUFFIX}"
DAILY_FILENAME="${DB}-`date +%Y%m%d`${BACKUP_SUFFIX}"
WEEKLY_FILENAME="${DB}-`date +%G%V`${BACKUP_SUFFIX}"
MONTHY_FILENAME="${DB}-`date +%Y%m`${BACKUP_SUFFIX}"
FILE="${BACKUP_DIR}/last/${LAST_FILENAME}"
DFILE="${BACKUP_DIR}/daily/${DAILY_FILENAME}"
WFILE="${BACKUP_DIR}/weekly/${WEEKLY_FILENAME}"
MFILE="${BACKUP_DIR}/monthly/${MONTHY_FILENAME}"
#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
#Copy (hardlink) for each entry
if [ -d "${FILE}" ]; then
DFILENEW="${DFILE}-new"
WFILENEW="${WFILE}-new"
MFILENEW="${MFILE}-new"
rm -rf "${DFILENEW}" "${WFILENEW}" "${MFILENEW}"
mkdir "${DFILENEW}" "${WFILENEW}" "${MFILENEW}"
ln -f "${FILE}/"* "${DFILENEW}/"
ln -f "${FILE}/"* "${WFILENEW}/"
ln -f "${FILE}/"* "${MFILENEW}/"
rm -rf "${DFILE}" "${WFILE}" "${MFILE}"
echo "Replacing daily backup ${DFILE} folder this last backup..."
mv "${DFILENEW}" "${DFILE}"
echo "Replacing weekly backup ${WFILE} folder this last backup..."
mv "${WFILENEW}" "${WFILE}"
echo "Replacing monthly backup ${MFILE} folder this last backup..."
mv "${MFILENEW}" "${MFILE}"
else
echo "Replacing daily backup ${DFILE} file this last backup..."
ln -vf "${FILE}" "${DFILE}"
echo "Replacing weekly backup ${WFILE} file this last backup..."
ln -vf "${FILE}" "${WFILE}"
echo "Replacing monthly backup ${MFILE} file this last backup..."
ln -vf "${FILE}" "${MFILE}"
fi
# Update latest symlinks
echo "Point last backup file to this last backup..."
ln -svf "${LAST_FILENAME}" "${BACKUP_DIR}/last/${DB}-latest${BACKUP_SUFFIX}"
echo "Point latest daily backup to this last backup..."
ln -svf "${DAILY_FILENAME}" "${BACKUP_DIR}/daily/${DB}-latest${BACKUP_SUFFIX}"
echo "Point latest weekly backup to this last backup..."
ln -svf "${WEEKLY_FILENAME}" "${BACKUP_DIR}/weekly/${DB}-latest${BACKUP_SUFFIX}"
echo "Point latest monthly backup to this last backup..."
ln -svf "${MONTHY_FILENAME}" "${BACKUP_DIR}/monthly/${DB}-latest${BACKUP_SUFFIX}"
#Clean old files
echo "Cleaning older files for ${DB} database from ${POSTGRES_HOST}..."
find "${BACKUP_DIR}/last" -maxdepth 1 -mmin "+${KEEP_MINS}" -name "${DB}-*${BACKUP_SUFFIX}" -exec rm -rvf '{}' ';'
find "${BACKUP_DIR}/daily" -maxdepth 1 -mtime "+${KEEP_DAYS}" -name "${DB}-*${BACKUP_SUFFIX}" -exec rm -rvf '{}' ';'
find "${BACKUP_DIR}/weekly" -maxdepth 1 -mtime "+${KEEP_WEEKS}" -name "${DB}-*${BACKUP_SUFFIX}" -exec rm -rvf '{}' ';'
find "${BACKUP_DIR}/monthly" -maxdepth 1 -mtime "+${KEEP_MONTHS}" -name "${DB}-*${BACKUP_SUFFIX}" -exec rm -rvf '{}' ';'
done
echo "SQL backup created successfully"
# Post-backup hook
if [ -d "${HOOKS_DIR}" ]; then
run-parts -a "post-backup" --reverse --exit-on-error "${HOOKS_DIR}"
fi