Skip to content

Instantly share code, notes, and snippets.

@aleksandr-vin
Last active September 12, 2023 12:12
Show Gist options
  • Save aleksandr-vin/41ee2062e978f2f680fd190c7e957dab to your computer and use it in GitHub Desktop.
Save aleksandr-vin/41ee2062e978f2f680fd190c7e957dab to your computer and use it in GitHub Desktop.
Backup and restore docker volume data
#!/usr/bin/env bash
#
# Script to backup and restore docker volume data
#
# Example:
#
# BACKUPPED_PATH=/var/lib/postgresql/data BACKUPPED_VOLUME=my-db-volume ./db-volume-backup.sh backup my-db-volume-backup
#
set -e
#set -x
OP="$1"
BACKUP_NAME="$2"
usage() {
cat <<EOF
Backup and restore docker volume data.
Usage:
$(basename $0) (backup|restore) (backup-name)
EOF
}
if [[ "$BACKUP_NAME" == "" ]]
then
usage
exit 1
fi
checks() {
if docker ps --filter "volume=${BACKUPPED_VOLUME?}" --format "{{.Names}}" | grep Up
then
echo >&2 "Containers using ${BACKUPPED_VOLUME?} volume found running. Stop them before retry."
exit 3
fi
}
case "$OP" in
backup)
checks
# Create a temporary container which mounts the volume
docker run --rm -v ${BACKUPPED_VOLUME?}:${BACKUPPED_PATH?} -d --name backup-${BACKUPPED_VOLUME?} busybox sleep 1d >/dev/null
temp_dir=$(mktemp -d)
trap "rm -rf "$temp_dir" & docker stop backup-${BACKUPPED_VOLUME?} &" EXIT
# Use docker cp to copy data to the host
docker cp backup-${BACKUPPED_VOLUME?}:${BACKUPPED_PATH?} "$temp_dir/backup"
# Stop and remove the temporary container
docker stop backup-${BACKUPPED_VOLUME?}
trap "rm -rf "$temp_dir" &" EXIT
echo "Compressing..."
pwd=$(pwd)
(cd "$temp_dir" && tar czf "$pwd/${BACKUP_NAME?}.tar.gz" backup)
echo "Saved: $(du -h -s ${BACKUP_NAME?}.tar.gz)"
rm -rf "$temp_dir"
trap "" EXIT
;;
restore)
checks
# Create a temporary container which mounts the volume
docker run --rm -v ${BACKUPPED_VOLUME?}:${BACKUPPED_PATH?} -d --name backup-${BACKUPPED_VOLUME?} busybox sleep 1d >/dev/null
temp_dir=$(mktemp -d)
trap "rm -rf "$temp_dir" & docker stop backup-${BACKUPPED_VOLUME?} &" EXIT
echo "From: $(du -h -s ${BACKUP_NAME?}.tar.gz)"
# Extract the backup if it's compressed
tar xzf ${BACKUP_NAME?}.tar.gz -C "$temp_dir"
# Use docker cp to copy data to the volume
docker cp "$temp_dir/backup/." backup-${BACKUPPED_VOLUME?}:${BACKUPPED_PATH?}
# Stop and remove the temporary container
docker stop backup-${BACKUPPED_VOLUME?}
rm -rf "$temp_dir"
trap "" EXIT
;;
*)
usage
exit 2
;;
esac
@aleksandr-vin
Copy link
Author

aleksandr-vin commented Sep 12, 2023

Example run,
of backup:

% BACKUPPED_PATH=/var/lib/postgresql/data BACKUPPED_VOLUME=backend_db ./db-volume-backup.sh backup backend_db
Successfully copied 950MB to /var/folders/tn/grglkq4521sgkw60t257zmw00000gq/T/tmp.heBAqDkj/backup
backup-backend_db
Compressing...
Saved: 176M	backend_db.tar.gz

and restore:

% BACKUPPED_PATH=/var/lib/postgresql/data BACKUPPED_VOLUME=backend_db ./db-volume-backup.sh restore backend_db
From: 176M	backend_db.tar.gz
Successfully copied 950MB to backup-backend_db:/var/lib/postgresql/data
backup-backend_db

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment