Skip to content

Instantly share code, notes, and snippets.

@DrJume
Last active November 26, 2024 13:40
Show Gist options
  • Save DrJume/ddb391562a7eb4b72644dde0ef811873 to your computer and use it in GitHub Desktop.
Save DrJume/ddb391562a7eb4b72644dde0ef811873 to your computer and use it in GitHub Desktop.
Backup all mounted volumes in a Docker container into a .tar.gz archive
#!/bin/bash
# Author: @DrJume
# This script lets you backup all mounted volumes of a Docker container
# into a .tar.xz archive.
# Throw on nonzero exit in pipelines
set -e
# Throw on paramter expansion on unset variables.
set -u
# log every exectued command
# set -x # during dev
printUsage() {
cat <<EOF >/dev/stderr
Usage: $0 container_id|container_name [backup_destination] [-xz compression_level]
container_id, ID or name of a Docker container.
container_name
backup_destination Path to where to create the tarball.
Default: . (current working dir)
EOF
}
if [[ $# -lt 1 ]]; then
printUsage
exit 1
fi
CONTAINER="$1"
BACKUP_DESTINATION=$PWD
if [[ -n ${2:-} ]]; then
BACKUP_DESTINATION+="/${2:-}"
fi
# check if Docker container exists
if ! docker inspect $CONTAINER > /dev/null ; then
echo "No such container: $CONTAINER"
exit 2
fi
MOUNTS=($(docker inspect --format="{{range .Mounts}}{{.Destination}} {{end}}" $CONTAINER))
VOLUMES_NAMES=($(docker inspect --format="{{range .Mounts}}{{.Name}} {{end}}" $CONTAINER))
TRANSFORM_EXPR=()
for i in "${!MOUNTS[@]}"; do
mount=${MOUNTS[$i]#/} # strip leading '/'
volume_name=${VOLUMES_NAMES[$i]}
TRANSFORM_EXPR+=("--transform='s,^$mount,${volume_name:-mount},'")
done
unset mount
unset volume_name
TAR_CMD="tar -czvf /backup/${CONTAINER}_$(date +%F_%H-%M-%S).tar.gz ${TRANSFORM_EXPR[*]} --show-transformed-names ${MOUNTS[*]}"
echo "Running: $TAR_CMD"
read -s -n 1 -p "Press any key to continue..."; echo
# attach all volumes from container as read-only (:ro)
( docker run --rm --volumes-from "$CONTAINER:ro" -v "$BACKUP_DESTINATION:/backup" --name "${CONTAINER}_backup" ubuntu bash -c "$TAR_CMD" ) \
| less -P "Press 'q' to continue..."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment