This method is not perfect; new incoming messages during message store backup will be lost in a restore.
Install the epel repo:
rpm -ivh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-5.noarch.rpm yum update
Then,
yum -y install duplicity
Create a volume group for backup:
pvcreate /dev/sdd1 vgcreate vg2 /dev/sdd1 lvcreate -l 100%FREE -n lv_backup vg2
mkdir -p /backup/opt-zimbra-mirror mkdir -p /backup/opt-zimbra mkdir -p /backup/zdata mkdir -p /backup/var
Use third party smtp server and mailbox to receive alert, as the zimbra server may not function in an error condition.
#!/bin/sh
# Script file: /usr/local/bin/backup-zimbra.sh
# schedule this to run as root every day during least busy hours
mailer="/bin/mailx -r root@zimbra.example.com -S smtp=smtp.isp.net"
do_fail() {
# email the admin about the failure
echo "$1"
echo "$1" >> /tmp/zimbra-backup.msg
echo "" >> /tmp/zimbra-backup.msg
cat /var/log/rsync-zimbra.log >> /tmp/zimbra-backup.msg
echo "" >> /tmp/zimbra-backup.msg
cat /tmp/duplicity.log >> /tmp/zimbra-backup.msg
cat /tmp/zimbra-backup.msg | ${mailer} -s "Backup Error" backup.alert@gmail.com
logger -t ZimbraBackup "$1"
exit 1
}
do_ok() {
# email the admin about the success
echo "$1"
echo "$1" >> /tmp/zimbra-backup.msg
echo "" >> /tmp/zimbra-backup.msg
cat /var/log/rsync-zimbra.log >> /tmp/zimbra-backup.msg
echo "" >> /tmp/zimbra-backup.msg
cat /tmp/duplicity.log >> /tmp/zimbra-backup.msg
cat /tmp/zimbra-backup.msg | ${mailer} -s "Backup OK" backup.alert@gmail.com
logger -t ZimbraBackup "$1"
exit 0
}
if [ "x$1" = "xfull" ] ; then
# full backup
dup_mode="full"
else
dup_mode="incremental"
fi
# start
logger -t ZimbraBackup "Start updating the cold snapshot ..."
# clear logs
cat /dev/null > /tmp/zimbra-backup.msg
cat /dev/null > /var/log/rsync-zimbra.log
cat /dev/null > /tmp/duplicity.log
# check backup dir
[ -d "/backup/opt-zimbra-mirror/" ] || do_fail "Backup volume not mounted!"
# do live sync first
logger -t ZimbraBackup "do live zimbra sync first ..."
rsync -av --stats --log-file /var/log/rsync-zimbra.log \
--exclude 'store/*' --exclude 'index/*' \
/opt/zimbra/ /backup/opt-zimbra-mirror/
r=$?
[[ ! "$r" = "0" ]] && do_fail "live rsync failed!"
# stop zimbra for cold backup
logger -t ZimbraBackup "stop zimbra for cold rsync ..."
/etc/init.d/zimbra stop
r=$?
if [ ! "$r" = "0" ] ; then
/etc/init.d/zimbra start
do_fail "Failed to stop Zimbra!"
fi
# re-run rsync as cold backup now:
logger -t ZimbraBackup "re-run rsync on cold zimbra ..."
rsync -av --stats --log-file /var/log/rsync-zimbra.log \
--exclude 'store/*' --exclude 'index/*' \
/opt/zimbra/ /backup/opt-zimbra-mirror/
r=$?
[[ ! "$r" = "0" ]] && do_fail "cold rsync failed!"
# re-start zimbra after done
/etc/init.d/zimbra start
r=$?
if [ ! "$r" = "0" ] ; then
logger -t ZimbraBackup "Failed to start Zimbra!"
fi
# At this point the cold snapshot is ready
logger -t ZimbraBackup "cold snapshot is now ready."
# backup the index and store
# logger -t ZimbraBackup "start backup the message index and store ..."
# duplicity ${dup_mode} --no-encryption --volsize 999 /zdata/ file:///backup/zdata >> /tmp/duplicity.log 2>&1
# r=$?
# [[ ! "$r" = "0" ]] && do_fail "backup of message index and store failed!"
# backup the snapshot
logger -t ZimbraBackup "Starting ${dup_mode} back up of the snapshot ..."
duplicity ${dup_mode} --no-encryption --volsize 999 /backup/opt-zimbra-mirror/ file:///backup/opt-zimbra >> /tmp/duplicity.log 2>&1
r=$?
[[ ! "$r" = "0" ]] && do_fail "backup of snapshot failed!"
# housekeeping by deleting old backup sets (older tha 28 days )
duplicity remove-older-than 28D --force file:///backup/opt-zimbra >> /tmp/duplicity.log 2>&1
r=$?
if [ ! "$r" = "0" ] ; then
logger -t ZimbraBackup "House keeping failed!"
do_ok "Backup completed with error."
else
do_ok "Backup completed successfully."
fi
Schedule it with cron:
cat <<EOT > /etc/cron.d/backup-zimbra # Incremental Backup on Tue-Sun at 01:01 1 1 * * 2-7 root /usr/local/bin/backup-zimbra.sh # Full Backup on Mon at 01:01 1 1 * * 1 root /usr/local/bin/backup-zimbra.sh full EOT touch /etc/crontab
To backup all folders including contacts, calender… for demo1@zimbra.example.com to a tgz file:
su - zimbra zmmailbox -z -m demo1@zimbra.example.com getRestURL '//?fmt=tgz' > /backup/mailboxes/demo1.tgz
You can use this skeleton to build a script to backup all mailboxes in the server.
To restore, set the account status to Maintenance. Then either use the web UI: Login as demo1, go to preferences » import/export » import the demo1.tgz file
Or use CLI:
su - zimbra zmmailbox -z -m demo1@zimbra.example.com postRestURL "//?fmt=tgz&resolve=reset" /backup/mailboxes/demo1.tgz # option: resolve=reset means overwrite all existing folders and their contents
Remove backups older than 28 days:
find /backup/ -type d -mtime +28 -exec rm -rf {} \;