/
backup_wordpress.sh
executable file
·142 lines (121 loc) · 3.76 KB
/
backup_wordpress.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
#!/bin/bash
#
# Assumptions:
# - DOCROOT/backup is created with desired owner, group, and permissions by
# system configuration
# - WordPress is installed in DOCROOT/wp
# - The uploads directory is in DOCROOT/wp-content
# - WP CLI is installed at /usr/local/bin/wp
# - /opt/wp-cli/silence.php exists and contains something like:
# <?php error_reporting(0); @ini_set("display_errors", 0);
#
#
# This script creates the following backups (if invoked with each interval):
#
# /var/www/SITE/backup
# │
# ├── daily
# │ ├── backup_id_2019-04-05-1379620 # (Provides timestamp of backup)
# │ ├── db.sql.gz # Compressed database dump
# │ └── uploads.tgz # Compressed tarball of uploads
# │ # directory
# ├── now
# │ ├── backup_id_2019-04-05-a427ee7
# │ ├── db.sql.gz
# │ └── uploads.tgz
# │
# └── weekly
# ├── backup_id_2019-04-05-04ebe43
# ├── db.sql.gz
# └── uploads.tgz
#
set -o errexit
set -o errtrace
set -o nounset
trap '_es=${?};
_lo=${LINENO};
_co=${BASH_COMMAND};
echo "${0}: line ${_lo}: \"${_co}\" exited with a status of ${_es}";
exit ${_es}' ERR
#### FUNCTIONS ########################################################
backup_database() {
# https://developer.wordpress.org/cli/commands/db/export/
/usr/local/bin/wp --quiet --no-color --require=/opt/wp-cli/silence.php \
--path="${DOCROOT}/wp" db export --single-transaction - | \
gzip > ${DESTINATION}/db.sql.gz
chmod g+w ${DESTINATION}/db.sql.gz
}
backup_uploads() {
tar zcf ${DESTINATION}/uploads.tgz -C ${DOCROOT}/wp-content \
uploads
chmod g+w ${DESTINATION}/uploads.tgz
}
error_exit() {
# Display error message and exit
local _es _msg
_msg=${1}
_es=${2:-1}
echo "ERROR: ${_msg}" 1>&2
exit ${_es}
}
prep_and_erase_backup_destination() {
DESTINATION="${DOCROOT}/backup/${INTERVAL}"
if [[ -d "${DESTINATION}" ]]
then
rm -f "${DESTINATION}"/*
else
mkdir "${DESTINATION}"
fi
chmod g+w ${DESTINATION} 2>/dev/null || true
local today=$(date -u '+%F')
local hash=$(date | md5sum)
local hash=${hash:1:7}
echo "# ${today}" > ${DESTINATION}/backup_id_${today}-${hash}
chmod g+w ${DESTINATION}/backup_id_${today}-${hash}
}
validate_requirements() {
command -v /usr/local/bin/wp >/dev/null || \
error_exit 'the WP CLI is not installed or not in the PATH.'
}
validate_docroot() {
[[ -n "${DOCROOT}" ]] || \
error_exit 'the first argument, DOCROOT, is required.'
[[ -d "${DOCROOT}" ]] || \
error_exit 'invalid DOCROOT specified. Directory does not exit.'
[[ -d "${DOCROOT}/backup" ]] || \
error_exit 'DOCROOT does not contain a backup directory.'
DOCROOT=${DOCROOT%/}
}
validate_interval() {
if [[ -z "${INTERVAL}" ]]
then
{
echo 'WARNING: the second argument, INTERVAL, is missing.'
echo ' The value of "now" will be used.'
echo -n ' Pausing for 5 seconds'
for i in {1..5}
do
echo -n ' .'
sleep 1
done
echo
} 1>&2
INTERVAL=now
fi
if [[ "${INTERVAL}" != 'now' ]] && \
[[ "${INTERVAL}" != 'daily' ]] && \
[[ "${INTERVAL}" != 'weekly' ]]
then
error_exit \
'invalid INTERVAL specified. Must be "now", "daily", or "weekly".'
fi
}
#### MAIN #############################################################
DOCROOT=${1:-}
INTERVAL=${2:-}
validate_requirements
validate_docroot
validate_interval
prep_and_erase_backup_destination
backup_database
backup_uploads