✨
Docker のvolumeのbackupとrestore
概要
MySQLのデータベースをDockerのvolumeにマウントしているときのバックアップするためのshell scriptです。
考え方は以下の通りです。
- バックアップ用shell script
create_snapshot.sh
- MySQLのデータベースのDockerのvolumeと別途バックアップ用のvolumeを作業用のubuntuにマウントして、バックアップ用のvolumetarでコピーします。
sh create_snapshot.sh -t docker_volume_backup_shell_script_db_data -b bck_volume
- リストア用shell script
restore_snapshot.sh
- MySQLのデータベースのDockerのvolumeと別途バックアップ用のvolumeを作業用のubuntuにマウントして、tarファイルをMySQLのデータベースのDockerのvolumeに解凍します。
sh restore_snapshot.sh -t docker_volume_backup_shell_script_db_data -b bck_volume
試し用のリポジトリ
MySQLを例にして、ためせるリポジトリを作りました。
README上から順番に打ち込んで、バックアップとリストアができることを体験ください。
シェルスクリプト
バックアップ用shell script
while getopts b:t:i OPTION; do
case $OPTION in
b) bck_volume=$OPTARG ;;
t) tgt_volume=$OPTARG ;;
i) bck_docker_image=$OPTARG ;;
esac
done
if [ -z "$bck_volume" ]; then
echo '-b must be needed. Please write back up Docker volume name.'
exit 1
fi
if [ -z "$tgt_volume" ]; then
echo '-t must be needed. Please write back up target Docker volume name.'
exit 1
fi
if [ -z "$work_docker_image" ]; then
work_docker_image="ubuntu:latest"
fi
bck_directory="bck"
tgt_directory="tgt"
bck_tar_file="bck.tar"
echo '===START==='
echo '===START RESET BACKUP VOLUME===' &&
docker volume rm -f $bck_volume &&
docker volume create $bck_volume &&
echo '===END RESET BACKUP VOLUME===' &&
echo '===START BACKUP===' &&
docker run --rm -v $bck_volume:/$bck_directory -v $tgt_volume:/$tgt_directory $work_docker_image bash -c "cd / && tar cvf $bck_directory/$bck_tar_file $tgt_directory" &&
echo "===Docker volume [$tgt_volume] is copied to [$bck_tar_file] file in Docker volume [$bck_volume] ===" &&
echo '===END BACKUP===' &&
echo '===FINISH==='
while getopts b:t:i OPTION; do
case $OPTION in
b) bck_volume=$OPTARG ;;
t) tgt_volume=$OPTARG ;;
i) bck_docker_image=$OPTARG ;;
esac
done
ここでoption引数をとります。 -b
, -t
, -i
を引数に取ることができます。
-
-b
はbck_volume
変数。これは、バックアップを保存するDocker volume名です。 -
-t
はtgt_volume
変数。これは、バックアップ元のDocker volume名です。 -
-i
はbck_docker_image
変数。これは、volumeをマウントしてtarコマンドを実行するdocker imageです。defaultはubuntu:latest
です。tarが実行できればどんなimageでもいいです。
if [ -z "$bckup_volume" ]; then
bck_volume="bck_volume"
fi
-b
と-t
は、必ず指定して欲しいので、指定されていない場合は、exit 1
としてエラーとしています。
docker volume rm -f $bck_volume &&
docker volume create $bck_volume &&
バックアップ用のボリュームを一旦削除して、作り直します。
docker run --rm -v $bck_volume:/$bck_directory -v $tgt_volume:/$tgt_directory $work_docker_image bash -c "cd / && tar cvf $bck_directory/$bck_tar_file $tgt_directory"
バックアップ元とバックアップ先の両方のvolumeをマウントし、 tar cvf バックアップ先 バックアップ元
でtarファイルにバックアップします。
リストア用shell script
while getopts b:t:i OPTION; do
case $OPTION in
b) bck_volume=$OPTARG ;;
t) tgt_volume=$OPTARG ;;
i) work_docker_image=$OPTARG ;;
esac
done
if [ -z "$bck_volume" ]; then
echo '-b must be needed. Please write back up Docker volume name.'
exit 1
fi
if [ -z "$tgt_volume" ]; then
echo '-t must be needed. Please write back up target Docker volume name.'
exit 1
fi
if [ -z "$work_docker_image" ]; then
work_docker_image="ubuntu:latest"
fi
bck_directory="bck"
tgt_directory="tgt"
bck_tar_file="bck.tar"
echo '===START==='
echo '===START RESET TARGET VOLUME===' &&
echo "===Delete all data in [$tgt_volume] Docker volume." &&
docker run --rm -v $tgt_volume:/$tgt_directory $work_docker_image bash -c "rm -rf $tgt_directory/*" &&
echo '===END RESET TARGET VOLUME===' &&
echo '===START COPY BACKUP VOLUME TO TARGET DIRECTORY===' &&
echo "=== Restore data from [$bck_tar_file] in [$bck_volume] Docker volume to [$tgt_volume] Docker volume." &&
docker run --rm -v $bck_volume:/$bck_directory -v $tgt_volume:/$tgt_directory $work_docker_image bash -c "cd /$tgt_directory && tar -xvf /$bck_directory/$bck_tar_file --strip-components=1" &&
echo '===END COPY BACKUP VOLUME TO TARGET DIRECTORY==='
echo '===FINISH==='
引数の考え方は、バックアップ用shell script
と同じです。
docker run --rm -v $tgt_volume:/$tgt_directory $work_docker_image bash -c "rm -rf $tgt_directory/*"
一旦バックアップ元のvolumeをrm -rf
で削除します。
docker run --rm -v $bck_volume:/$bck_directory -v $tgt_volume:/$tgt_directory $work_docker_image bash -c "cd /$tgt_directory && tar -xvf /$bck_directory/$bck_tar_file --strip-components=1"
基本は、バックアップ用shell script
と同じです。 バックアップ元とバックアップ先のvolumeを両方マウントしtar xvf
でリストアします。
特記すべきは --strip=1
です。これがないと、tarでまとめたフォルダ名が作られてしまいます。--strip=1
をつけることにより、階層を一つ飛ばすことができます。
結果的に最上位のフォルダが作られません。
--strip-components=NUMBER
抽出時にファイル名の先頭から NUMBER 個の構成要素 (訳注: 要するに、NUMBER 個のディレクトリ部分) を取り去る
Discussion