✨
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