Docker volumeの移行(バックアップとリストア)

dockervolumeの移行の個人的なメモ。利用は自己責任にて。

すること

docker-machine env defaultでのdocker環境でのvolumeを、docker desktop環境でのvolumeに移行する。

バックアップするスクリプトと、リストアするスクリプトの2つを用意した。 簡単なスクリプトなので、色々ハードコードしている。

簡単な流れ

Use volumes | Docker Documentationの流れとほとんど同じ。volumeが結構な数あったので、スクリプトを使った。

まとめると次のような流れとなる。

  1. 既存のvolumeがある。
  2. バックアップ作成用のワンオフなコンテナを、対象のvolumeとローカルのディレクトリをマウントして、新規に起動。
  3. このコンテナ起動時にバックアップをマウントしたローカルディレクトリに作成する。ここまででバックアップは完了。
  4. 移行先のvolumeを用意する。
  5. 2と同じように、ワンオフなコンテナを、移行先のvolumeをローカルのディレクトリをマウントして、新規に起動。

5のコンテナの実行が終われば移行終了。

バックアップ

ポイントは特にない。名前を付けたvolumeだけ取り出すのもしんどいので、docker volume ls | awk 'NR>1 {print "VOLUME_LIST+=(\"" $2 "\")"}' | pbcopyでコピペして、不要なvolumeは含めないことにした。

create_backup_docker_volume.sh
GitHub Gist: instantly share code, notes, and snippets.
#!/bin/bash

###########################
#
#注意: このスクリプトが存在するフォルダから実行することを前提としている。
#
#pwdの場所に
#ハードコードされたdocker環境(docker-machineのdefault)の
#docker volumeのバックアップを取る。
#
###########################

#docker volume ls | awk 'NR>1 {print "VOLUME_LIST+=(\"" $2 "\")"}' | pbcopy
#上のコマンドでコピペできる。
VOLUME_LIST=(...)


echo virtualbox上のDocker環境をセットアップ...
eval $(docker-machine env)
if [ $? -eq 0 ]; then
    CHK=$(env | grep DOCKER)
    if [ ${#CHK} -lt 1 ]; then
        echo 環境変数がセットされていません
        exit -1
    fi
    echo 以前の環境からvolumeの中身を抽出...
    for vol in "${VOLUME_LIST[@]}"
    do
        docker run --rm -v ${vol}:/vol_data -v $(pwd):/backup ubuntu tar cvf /backup/backup_${vol}.tar /vol_data
        if [ $? -ne 0 ]; then
            echo ${vol}のバックアップに失敗しました。中止します。
            exit -2
        fi
    done
else
    echo 失敗
    exit -1
fi

echo virtualbox上のDocker環境を終了。volumeのバックアップは~/Desktopに作成されました。
echo 終了します。
exit 0

dockertarコマンドが分かっていれば問題ないと思う。

リストア

ポイントは、既に同名のvolumeがあるときは消したほうがいいかもしれないということ(どうなっても知らない)。volumeを使っているコンテナがあれば停止しておく。

restore_backup_docker_volume.sh
GitHub Gist: instantly share code, notes, and snippets.
#!/bin/bash

###########################
#
#注意: このスクリプトが存在するフォルダから実行することを前提としている。
#
#docker desktop環境に別環境のvolumeを復元する。
#docker desktopにある同名のvolumeは、削除される。
#
###########################

#docker volume ls | awk 'NR>1 {print "VOLUME_LIST+=(\"" $2 "\")"}' | pbcopy
#上のコマンドでコピペできる。
VOLUME_LIST=(...)

echo Docker Desktop環境に移行...
eval $(docker-machine env -u)
if [ $? -eq 0 ]; then
    echo Docker Desktopに既に存在するこれらのvolumeを削除していいですか?
    echo ${VOLUME_LIST[@]}
    echo -n 以上のうち存在するvolumeが削除されます。よろしいですか? [y/n]:
    read yn
    case "$yn" in
        [yY] ) echo ok ;;
        * ) echo 処理を中止します。 ;exit 2 ;;
    esac
    for vol in "${VOLUME_LIST[@]}"
    do
        docker volume rm ${vol}
    done
    echo 既存のvolumeの削除を終了...

    #volumeの作成・復元
    backups=($(ls | grep tar))
    for bu in "${backups[@]}"
    do
        volname=$(echo $bu | sed -e "s/backup_//g" | sed -e "s/.tar//g")
        docker volume create ${volname}
        echo ボリューム${volname}を作成・リストア...
        docker run --rm -v ${volname}:/vol_data -v $(pwd):/backup ubuntu bash -c "cd /vol_data && tar xvf /backup/${bu} --strip 1"
        echo ボリューム${volname}のリストアが完了
    done
else
    echo 失敗
    exit -1
fi
echo 全ての処理が終了しました。

こちらもdockertarコマンドが分かっていればいいだろう。

終わり

既存のvolumeの確認がうまく作れてないと思う。確認はするようにしたからいいだろう…ということにしておく。 shellスクリプトはサクッと文法を使いこなして書けるようにしたい。

volumeは主にDBなどの格納に利用していて、DBのダンプなどを考えずにバックアップを取れるのはいいポイントになるんじゃないかと思う。

ビジュアルエディタじゃないとgistのコードが表示されないようだ。

タイトルとURLをコピーしました