Skip to content

Instantly share code, notes, and snippets.

@lecoueyl
Last active March 13, 2018 06:23
Show Gist options
  • Save lecoueyl/0cf49d38fa0b0205f51ca9db75b1f548 to your computer and use it in GitHub Desktop.
Save lecoueyl/0cf49d38fa0b0205f51ca9db75b1f548 to your computer and use it in GitHub Desktop.
Bash script to backup a wordpress folder and database then transfert it to google storage (optional)
#!/usr/bin/env bash
# Archive a wordpress folder with is database
# Usage: ./wp-backup.sh -s '/my/wordpress/folder' -d $HOME -g 'my-google-space-bucket'
#
#
# Source: https://gist.githubusercontent.com/lecoueyl/0cf49d38fa0b0205f51ca9db75b1f548/raw
set -o pipefail
set -o nounset
# Options
################################################################################
_usage() {
echo -e "Available options:" && grep " .)\ #" $0;
exit 0;
}
while getopts ":s:d:n:k:g:rh:" arg; do
case $arg in
s) # Source of the wordpress folder
readonly __source=${OPTARG}
;;
d) # Destination folder to backup data
readonly __dest=${OPTARG}
;;
n) # Backup name (default: source directory name)
name=${OPTARG}
;;
k) # Number of backup to keep (default: 3)
keep_backup=${OPTARG}
;;
g) # Google storage bucket name (optional)
readonly __google_bucket=${OPTARG}
;;
h) # Show help
_usage
;;
*)
_usage
;;
esac
done
if [ -z "${__source+x}" ]; then
echo -e "You need to specify the wordpress folder"
_usage
fi
if [ -z "${__dest+x}" ]; then
echo -e "You need to specify where to backup the files"
_usage
fi
# Constant
################################################################################
# Colors
readonly __info=$'\e[34m'
readonly __alert=$'\e[91m'
readonly __warning=$'\e[33m'
readonly __nocolor=$'\e[0m'
# Assets
readonly __backup_folder="wp-backup"
readonly __exclude="${exclude:-".git*"}"
readonly __keep_backup="${keep_backup:-3}"
# Functions
################################################################################
#
# Global
#
_log::info() {
echo -e " $1"
}
_log::error() {
echo -e "\n ${__alert}$1${__nocolor}" >&2
exit 1
}
#
# Init
#
_backup::init() {
_set_assets() {
# source
if [ ! -d "${__source}" ]; then
_log::error "Wordpress folder not found in ${__source} "
fi
readonly __source_relative_path="$(cd "${__source}" && pwd)"
readonly __source_basename="${name:-$(basename ${__source})}"
readonly __wp_config_file="${__source_relative_path}/wp-config.php"
if [ ! -f "${__wp_config_file}" ]; then
_log::error "Configuration file not found in ${__wp_config_file}"
fi
# destination
if [ ! -d "${__dest}" ]; then
_log::error "Destination folder not found in ${__dest}"
fi
readonly __backup_path="${__dest}/${__backup_folder}/${__source_basename}"
if ! mkdir -p "${__backup_path}" 2>/dev/null; then
_log::error "Could not create backup directory in ${__backup_path}"
fi
# timestamp
readonly __timestamp="$(date +%Y%m%d%H%M%S)"
}
_set_db_credential() {
readonly __db_name="$(grep -v '//' ${__wp_config_file} | grep DB_NAME | cut -d \' -f 4)"
readonly __db_user="$(grep -v '//' ${__wp_config_file} | grep DB_USER | cut -d \' -f 4)"
readonly __db_password="$(grep -v '//' ${__wp_config_file} | grep DB_PASSWORD | cut -d \' -f 4)"
readonly __db_host="$(grep -v '//' ${__wp_config_file} | grep DB_HOST | cut -d \' -f 4)"
readonly __db_config_file="${__source_relative_path}/${__db_name}-${__timestamp}.cnf"
readonly __db_output_file="${__source_relative_path}/${__db_name}-${__timestamp}.sql"
cat > ${__db_config_file} <<EOL
[client]
host="${__db_host}"
user="${__db_user}"
password="${__db_password}"
EOL
}
_set_assets
_set_db_credential
_log::info "Creating backup for ${__source_relative_path}"
}
#
# Wordpress
#
_backup::wordpress() {
_backup_database() {
if ! hash mysqldump 2>/dev/null; then
_log::error "Could not find command mysqldump"
fi
_log::info "Dumping database"
mysqldump \
--defaults-extra-file=${__db_config_file} \
--single-transaction \
--databases ${__db_name} > ${__db_output_file};
rm ${__db_config_file}
}
_archive_data() {
_log::info "Compressing"
readonly __archive_file="${__backup_path}/${__source_basename}-${__timestamp}.tar.gz"
cd ${__source_relative_path} && tar \
--dereference \
--create \
--gzip \
--file=${__archive_file} \
.
}
_backup_database
_archive_data
}
#
# Wordpress
#
_backup::upload() {
_upload_google_storage() {
if ! hash gsutil 2>/dev/null; then
_log::error "Could not find command gsutil"
fi
_log::info "Tranfering backup to gs://${__google_bucket}"
gsutil -m -q cp ${__archive_file} gs://${__google_bucket}/${__backup_folder}/${__source_basename}/
}
if [ ! -z "${__google_bucket+x}" ]; then
_upload_google_storage
fi
}
#
# Clean
#
_backup::clean() {
_remove_db_output() {
rm ${__db_output_file}
}
_remove_old_backup() {
local total_revision
total_revision="$(find ${__backup_path} -mindepth 1 -maxdepth 1 | wc -l 2>&1)"
if [[ $total_revision -gt $__keep_backup ]]; then
ls -t -d ${__backup_path}/** | sed -e "1,${__keep_backup}d" | xargs -d '\n' rm -r
fi
}
_remove_old_google_storage() {
gsutil -m ls -l gs://${__google_bucket}/${__backup_folder}/${__source_basename}/ | grep ${__google_bucket} | awk '{print $3}' | tac | sed -e "1,${__keep_backup}d" | xargs -d '\n' gsutil -q -m rm
}
_log::info "Cleaning"
_remove_db_output
_remove_old_backup
if [ ! -z "${__google_bucket+x}" ]; then
_remove_old_google_storage
fi
}
#
# Finish
#
_backup::finish() {
_log::info "Backup completed successfully"
}
# Backup flow
################################################################################
_backup::init
_backup::wordpress
_backup::upload
_backup::clean
_backup::finish
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment