15 Commits

Author SHA1 Message Date
Asif Bacchus 16f4c11f91 fix(BACKUP): remove extraneous mailcow dir in xtraLocation 2021-02-15 15:43:18 -07:00
Asif Bacchus 0bc0f8e5f9 refactor(BACKUP): update xtraLocation sample 2021-02-15 15:39:43 -07:00
Asif Bacchus 21e4a6774c docs(BACKUP): change xtraListPath description
- description was misleading, this is not a required variable
- holdover from importing
2021-02-15 15:37:32 -07:00
Asif Bacchus 7e739d96a1 feature(LOGWATCH): Update logwatch scripts
- add trailing newlines
- update search phrases to match logfile output
2021-02-15 15:31:05 -07:00
Asif Bacchus 61e505952d update TOC 2021-02-10 08:30:13 -07:00
Asif Bacchus 1939962b75 [README] add restore section 2021-02-10 08:08:18 -07:00
Asif Bacchus f2231c7074 fix(BACKUP): change borg cmd
- place common-options after borg command verb
- thanks to lluis

Closes github 7
2021-02-09 16:56:38 -07:00
Asif Bacchus 2747b10040 docs(RESTORE): remove misleading copied comments 2021-02-09 14:59:59 -07:00
Asif Bacchus 876f8eee9e fix(RESTORE): fix restore path when non-verbose
- non-verbose tar extraction was set to null path
2021-02-09 14:58:50 -07:00
Asif Bacchus 3a3b02685b make restore script executable 2021-02-09 08:30:06 -07:00
Asif Bacchus 85e34c73a3 feature(BACKUP): add compression option
- parameter to specify compression used by borg
- as requested by shaneonabike (via github)

Closes github 5
2021-02-09 08:22:48 -07:00
Asif Bacchus 9e592633b9 fix(BACKUP): bypass possible cd aliases 2021-02-09 08:03:23 -07:00
Asif Bacchus e127616800 fix(BACKUP): fix missing parameter shift
- docker timeout parameters
2021-02-09 08:02:34 -07:00
Asif Bacchus 053e45affc docs(RESTORE): add inline help 2021-02-09 07:46:42 -07:00
Asif Bacchus fb58c06489 fix(RESTORE): fix output to console when non-verbose 2021-02-09 07:13:12 -07:00
8 changed files with 95 additions and 28 deletions
+11 -2
View File
@@ -1,4 +1,4 @@
# Mailcow Backup Using borgbackup <!-- omit in toc -->
# Mailcow Backup Using borgbackup
This script automates backing up your Mailcow installation using borgbackup and a remote ssh-capable storage system. I suggest using rsync.net since they
have great speeds and a special pricing structure for borgbackup/attic users ([details here](https://www.rsync.net/products/attic.html)).
@@ -14,14 +14,19 @@ This script automates the following tasks:
- Runs 'borg prune' to make sure you are trimming old backups on your schedule
- Creates a clear, easy to parse log file so you can keep an eye on your backups and any errors/warnings
## Contents <!-- omit in toc -->
## contents
<!-- toc -->
- [quick start](#quick-start)
- [configuration file](#configuration-file)
- [running the script](#running-the-script)
- [scheduling your backup via cron](#scheduling-your-backup-via-cron)
- [restoring backups](#restoring-backups)
- [final notes](#final-notes)
<!-- tocstop -->
## quick start
Clone this repo or download a release file into a directory of your choosing. For all examples in this document, I will assume you will run the script from */scripts/backup*. Make sure the script file is executable and you protect the *.details* file since it contains things like your repo password:
@@ -111,6 +116,10 @@ Edit your root user's crontab and add an entry like this which would run the scr
7 1 * * * /scripts/backup/backup.sh -l /var/log/mailcow_backup.log > /dev/null 2>&1
```
## restoring backups
Starting with version 3.0, a *restore.sh* file has been included to semi-automate restoring your backups to a clean mailcow instance. There are a few steps required and they are better explained in the wiki than would be possible in a short write-up like this. Please check out the [restore process overview](https://git.asifbacchus.app/asif/MailcowBackup/wiki/8.0-Restore-overview) for more information.
## final notes
I think that's everything. For detailed information, please review the [wiki](https://git.asifbacchus.app/asif/MailcowBackup/wiki/_pages). If I've forgotten to document something there, please let me know. I know the wiki is long but, I hate how much stuff for Linux and open-source programs/scripts in general are so poorly documented especially for newbies and I didn't want to make that same mistake.
+6 -5
View File
@@ -36,12 +36,13 @@ borgRepoPassphrase="p@ssW0rd"
# FULL PATH where the associated keyfile for your repo is located -- relevant
# only if your repo requires a keyfile (i.e. 'keyfile' vs 'repokey') and if you
# are not using the default keyfile location
borgKeyfileLocation="/var/borgbackup/.config/borg/keys/server_address__repo_name"
#borgKeyfileLocation="/var/borgbackup/.config/borg/keys/server_address__repo_name"
# REQUIRED: path to text file containing a list (one per line) of files/
# directories to include in your backup. Since this is a generic backup script,
# nothing is defined by default. Therefore, ONLY files specified in this file
# will be backed up!
# additional files to backup
# by default, the script will only backup your mailcow program directory
# (e.g. /opt/mailcow-dockerized) and your mailcow data volumes. If you would
# like additional files included (perhaps certificates, system configuration,
# etc.) include those locations listed one item per line in the file below
# see repo wiki for more details
borgXtraListPath="/scripts/backup/xtraLocations.borg"
+22 -4
View File
@@ -164,6 +164,10 @@ scriptHelp() {
textblock "Path to write log file"
defaultsTextblock "(scriptPath/scriptName.log)"
newline
switchTextblock "--compression"
textblock "Compression algorithm(s) that borg should use. Please run 'borg help compression' for details."
defaultsTextblock "(not specified, use borg default of lz4)"
newline
switchTextblock "[SWITCH] -v | --verbose"
textblock "Log borg output with increased verbosity (list all files). Careful! Your log file can get very large very quickly!"
defaultsTextblock "(normal output, option is OFF)"
@@ -300,6 +304,15 @@ while [ $# -gt 0 ]; do
badParam empty "$@"
fi
;;
--compression)
# set borg archive compression
if [ -n "$2" ]; then
borgCompression="$2"
shift
else
badParam empty "$@"
fi
;;
-v|--verbose)
# set verbose logging from borg
borgCreateParams='--list --stats'
@@ -367,6 +380,7 @@ while [ $# -gt 0 ]; do
badParam empty "$@"
else
dockerStartTimeout="$2"
shift
fi
;;
-t2|--timeout-stop)
@@ -374,6 +388,7 @@ while [ $# -gt 0 ]; do
badParam empty "$@"
else
dockerStopTimeout="$2"
shift
fi
;;
*)
@@ -417,7 +432,10 @@ fi
if [ ! -f "$mcDockerCompose" ]; then
badParam dne "(--docker-compose)" "$mcDockerCompose"
fi
# set compression level if specified
if [ -n "$borgCompression" ]; then
borgCreateParams="${borgCreateParams} --compression ${borgCompression}"
fi
### read mailcow.conf and set vars as needed
# shellcheck source=./mailcow.conf.shellcheck
@@ -615,7 +633,7 @@ if [ "$use503" -eq 1 ]; then
fi
### change to mailcow directory so docker commands execute properly
cd "${mcConfig%/*}" || exitError 100 'Could not change to mailcow directory.'
\cd "${mcConfig%/*}" || exitError 100 'Could not change to mailcow directory.'
### stop postfix and dovecot mail containers to prevent mailflow during backup
doDocker stop postfix
@@ -672,7 +690,7 @@ printf "%s[%s] -- [INFO] Pre-backup tasks completed, calling borgbackup --%s\n"
## construct the proper borg commandline
# base command
if [ "$exclusions" -eq 0 ]; then
borgCMD="borg --show-rc create ${borgCreateParams} \
borgCMD="borg create --show-rc ${borgCreateParams} \
::$(date +%Y-%m-%d_%H%M%S) \
${mcConfig%/*} \
${sqlDumpDir} \
@@ -683,7 +701,7 @@ if [ "$exclusions" -eq 0 ]; then
${dockerVolumeCrypt} \
${xtraList}"
elif [ "$exclusions" -eq 1 ]; then
borgCMD="borg --show-rc create ${borgCreateParams} \
borgCMD="borg create --show-rc ${borgCreateParams} \
--exclude-from ${borgExcludeListPath} \
::$(date +%Y-%m-%d_%H%M%S) \
${mcConfig%/*} \
Regular → Executable
+45 -6
View File
@@ -57,7 +57,7 @@ doRestore() {
return 0
fi
else
if (! (cd "$sourceFiles/_data" && tar -cf - .) | (cd "${3}" && tar xvf -) ); then
if (! (cd "$sourceFiles/_data" && tar -cf - .) | (cd "${2}" && tar xvf -) > /dev/null 2>&1 ); then
return 1
else
return 0
@@ -71,8 +71,50 @@ doRestore() {
scriptHelp() {
textNewline
printf "%sUsage: %s [parameters]%s\n\n" "$bold" "$scriptName" "$norm"
textblock "The only required parameter is -b | --backup-location."
textblock "If a parameter is not supplied, its default value will be used."
textblock "Switch parameters will only be activated if specified."
textblockHeader "script parameters"
textblockParam "-b | --backup-location"
textblock "Directory containing extracted backup files from borg repo. REQUIRED."
textNewline
textblock "If a parameter is not supplied, its default value will be used. Switch parameters will remain DEactivated if NOT specified."
textblockParam "-l | --log" "scriptPath/scriptName.log"
textblock "Path to write log file. Best efforts will be made to create any specified paths."
textNewline
textblockParam "-v | --verbose" "false"
textblock "Enable verbose logging. This will list EVERY restored file possibly making your log file quite large! [SWITCH]"
textNewline
textblockParam "--skip-mail" "false"
textblock "Skip restoring mail and encryption key. [SWITCH]"
textNewline
textblockParam "--skip-sql" "false"
textblock "Skip restoring mailcow settings database. [SWITCH]"
textNewline
textblockParam "--skip-postfix" "false"
textblock "Skip restoring postfix settings. [SWITCH]"
textNewline
textblockParam "--skip-rspamd" "false"
textblock "Skip restoring Rspamd settings/configuration/history. [SWITCH]"
textNewline
textblockParam "--skip-redis" "false"
textblock "Skip restoring redis database. [SWITCH]"
textNewline
textblockParam "-? | -h | --help"
textblock "Display this help screen."
textblockHeader "mailcow parameters"
textblockParam "-d | --docker-compose" "/opt/mailcow-dockerized/docker-compose.yml"
textblock "FULL path to mailcow's 'docker-compose.yml' file."
textNewline
textblockParam "-m | --mailcow-config" "/opt/mailcow-dockerized/mailcow.conf"
textblock "FULL path to mailcow configuration file ('mailcow.conf'). The path of this file is also used to determine your mailcow directory."
textblockHeader "docker parameters"
textblockParam "-t1 | --timeout-start" "180"
textblock "Seconds to wait for docker containers to start."
textNewline
textblockParam "-t2 | --timeout-stop" "120"
textblock "Seconds to wait for docker containers to stop."
textNewline
textblock "More details and examples of script usage can be found in the repo wiki at ${yellow}https://git.asifbacchus.app/asif/MailcowBackup/wiki${norm}"
textNewline
exit 0
}
@@ -86,7 +128,7 @@ textblock() {
}
textblockHeader() {
printf "\n%s%s***%s***%s\n" "$bold" "$magenta" "$1" "$norm"
printf "\n%s%s*** %s ***%s\n\n" "$bold" "$magenta" "$1" "$norm"
}
textblockParam() {
@@ -458,7 +500,6 @@ if [ "$restorePostfix" -eq 1 ]; then
writeLog 'task' "Restoring postfix files"
fi
# restore email messages
doRestore "${COMPOSE_PROJECT_NAME}_postfix-vol-1" "$dockerVolumePostfix"; ec="$?"
case "$ec" in
0)
@@ -495,7 +536,6 @@ if [ "$restoreRspamd" -eq 1 ]; then
writeLog 'task' "Restoring Rspamd files"
fi
# restore email messages
doRestore "${COMPOSE_PROJECT_NAME}_rspamd-vol-1" "$dockerVolumeRspamd"; ec="$?"
case "$ec" in
0)
@@ -532,7 +572,6 @@ if [ "$restoreRedis" -eq 1 ]; then
writeLog 'task' "Restoring redis database"
fi
# restore email messages
doRestore "${COMPOSE_PROJECT_NAME}_redis-vol-1" "$dockerVolumeRedis"; ec="$?"
case "$ec" in
0)
+4 -4
View File
@@ -49,12 +49,12 @@
# include the paths to important configuration files/directories and/or
# data directories
# mailcow configuration (example)
/opt/mailcow-dockerized/
# mailcow configuration
# already backed-up by the script by default based on mailcow.conf location
# NGINX (example)
# NGINX (if this host is a reverse proxy, for example)
/etc/nginx/
/usr/share/nginx/html/
# LetsEncrypt (example)
# LetsEncrypt
/etc/letsencrypt/
+3 -3
View File
@@ -3,8 +3,8 @@
#############################################################################
# $Id$
#############################################################################
# Log: Backup script (backup)
# Revision 1.0 2018/10/16
# Log: mailcow backup
# Revision 1.1 2019/07/20
# Written by Asif Bacchus
#############################################################################
@@ -34,7 +34,7 @@ if ($detailLevel == 0) {
elsif ($ThisLine =~ /\-- \[WARNING\] /) {
$summaryWarn++;
}
elsif ($ThisLine =~ /All processes completed successfully/) {
elsif ($ThisLine =~ /All processes completed/) {
$summarySuccess++;
}
}