Skip to content

Instantly share code, notes, and snippets.

@jptissot
Created October 15, 2021 02:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jptissot/7711b62f45a2374b1f688549ed35a86b to your computer and use it in GitHub Desktop.
Save jptissot/7711b62f45a2374b1f688549ed35a86b to your computer and use it in GitHub Desktop.
Backup multiple docker container volumes to a single borg repository
#!/bin/bash
# Display Help
Help() {
echo
echo "docker-borg-backup"
echo "####################"
echo
echo "Description: Backup all docker volumes for specivic containers in a single borg repository."
echo "The borg repository is assumed to be initialized."
echo "Syntax: docker-borg-backup [-o|-c|help]"
echo "Example: docker-borg-backup -c pgadmin_prod,container_2 -o /mnt/backup"
echo "options:"
echo " -o Borg repository path. Defaults to '/mnt/backup/full-backup'"
echo " -c Docker container(s) name. Seperated by a comma"
echo " help Show docker-volume-backup manual."
echo
}
# Show help and exit
if [[ $1 == 'help' ]]; then
Help
exit
fi
# Process params
while getopts ":c: :o:" opt; do
case $opt in
c) containers="$OPTARG"
;;
o) dir="$OPTARG"
;;
\?) echo "Invalid option -$OPTARG" >&2
Help
exit;;
esac
done
# Fallback to environment vars and default values
: ${dir:='/mnt/backup/full-backup'}
# Verify variables
[[ -z "$dir" ]] && { echo "Parameter -o | borg repository path is empty" ; exit 1; }
[[ -z "$containers" ]] && { echo "Parameter -c | containers is empty" ; exit 1; }
# create the container array
IFS=',' read -ra container_array <<< "$containers"
# loop through each container and mount it's volumes
for container in "${container_array[@]}"
do
echo "stopping container $container"
docker container stop $container
vol_list=($(docker inspect -f '{{ range .Mounts }}{{ .Name }} {{ end }}' $container))
for vol in "${vol_list[@]}"
do
data_path=$(docker volume inspect --format '{{.Mountpoint}}' "$vol")
mnt_path=/mnt/borg/$vol
echo "mount volume $vol $data_path $mnt_path"
if [ ! -d $mnt_path ] ; then
sudo mkdir $mnt_path
sudo mount --bind -o ro $data_path $mnt_path
fi
done
done
backup_name=backup-$(date +%Y-%m-%d-%H%-M%S)
printf "backup name: %s\n" "$backup_name"
# Perform the backup
borg create --stats --compression lz4 --exclude '*.git' $dir::$backup_name /mnt/borg/
# Unmounting the volumes and restarting the containers
for container in "${container_array[@]}"
do
echo "restarting the container"
vol_list=($(docker inspect -f '{{ range .Mounts }}{{ .Name }} {{ end }}' $container))
for vol in "${vol_list[@]}"
do
mnt_path=/mnt/borg/$vol
echo "unmounting & removing $mnt_path for volume $vol"
sudo umount $mnt_path
sudo rm $mnt_path -vrf
done
echo "Restarting the container: $container"
docker container start $container
done
# Notify if backup has finished
echo "The Docker volume backup has finished"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment