scripts/docker/container.backup

119 lines
4.1 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/sh
# Purpose {{{
## Backup data of a Docker container.
## To do that, the script will:
## Try to stop the corresponding systemd unit (or docker if no related service is found)
## Make a archive of the container's data to a backup path
## Restart the container service (or docker.service)
## Clean old backup
# }}}
# How-to use {{{
## First argument should be the absolut path to the container's data.
## The data directory and the container should have the same name.
# }}}
# Vars {{{
DEBUG=1
## Nomber of backup to keep
keep_backup="3"
## Manage arguments {{{
## Expect at least 1 argument and 2 maximum
case $# in
1 )
## Absolut path to the container data
ct_data_path="${1}"
## Absolut path to store the archives.
## A sub-directory will be created for the container
docker_backup_path="/mnt/backup/docker"
;;
2 )
ct_data_path="${1}"
docker_backup_path="${2}"
;;
* )
cat << HELP
container.backup --
Backup data of a given Docker container.
EXAMPLE:
- Backup data of FIRST_CT container require the absolut path to data
container.backup /srv/docker/FIRST_CT
- Select the directory to store the backup of hello_world container
container.backup /srv/docker/hello_world /media/usb/docker.backup
HELP
exit 1
;;
esac
ct_name=$(basename -- "${ct_data_path}")
docker_data_path=$(dirname -- "${ct_data_path}")
ct_backup_path="${docker_backup_path}/${ct_name}"
## }}}
# }}}
# Tests {{{
## Ensure container data directory exists {{{
if [ ! -d "${ct_data_path}" ]; then
printf '\e[0;31m%-6s\e[m\n' "Docker data directory doesn't seems available: ${ct_data_path} ."
exit 1
else
[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG: Test arg — Path to Docker data: ${ct_data_path} ."
[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG: Test arg — Container name to backup: ${ct_name} ."
fi
## }}}
## Ensure backup directory exists {{{
if [ ! -d "${docker_backup_path}" ]; then
printf '\e[0;31m%-6s\e[m\n' "Backup directory doesn't seems available: ${docker_backup_path} ."
exit 1
else
[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG: Test arg — Path to store the backup: ${docker_backup_path} ."
fi
## }}}
# }}}
# Get container service name {{{
ct_service_name=$(find /etc/systemd -type f -iname "*${ct_name}*.service" -printf "%f\n")
## If no specific systemd service exists, the docker.service will be used
if [ "${ct_service_name}" = "" ]; then
ct_service_name="docker.service"
[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG: Service name — No specific service found for ${ct_name} container, the ${ct_service_name} will be stopped."
else
[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG: Service name — Service name of ${ct_name} container to stop: ${ct_service_name} ."
fi
# }}}
# Stop the container service {{{
systemctl stop "${ct_service_name}"
[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG: Service management — Service ${ct_service_name} was stopped."
# }}}
# Backup container data {{{
## Create the directory to store archive if doesn't already exist
if [ ! -d "${ct_backup_path}" ]; then
mkdir -p -- "${ct_backup_path}"
[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG: Backup data — ${ct_backup_path} was created."
fi
## Backup container data
tar czf "${ct_backup_path}/${ct_name}-backup.$(date '+%Y%m%d-%H%M').tar.gz" --directory "${docker_data_path}" "${ct_name}"
[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG: Backup data — Data of ${ct_name} container were successfully backuped ${ct_backup_path}/${ct_name}-backup.$(date '+%Y%m%d-%H%M').tar.gz"
# }}}
# Restart the container service {{{
systemctl start "${ct_service_name}"
[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG: Service management — Service ${ct_service_name} was started."
# }}}
# Remove old backups {{{
cd -- "${ct_backup_path}" || exit 1
[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6s\e[m\n' "DEBUG: Cleaning — Keep only the ${keep_backup} newest backups."
find . -type f | sort | head -n -"${keep_backup}" | xargs -d '\n' rm -f --
cd -- - > /dev/null || exit 1
# }}}
exit 0