註記 (2018/03/22)
この記事を書いてから長い月日が経ちましたが、じわじわといいねを頂いているようで…ありがとうございます。
ただ…正直この記事の内容はすでに太古の手法と化しています。
今のDockerではvolume機能を用いれば、ここに書かれた例のようにわざわざデータ永続化のためだけにコンテナを用意する必要も無くなります。
docker-composeであればデフォルトではvolumeのみ削除しない仕様なので、うっかりvolumeを闇に葬り去るという悲しい事件を起こしてしまうことも防げると思いますし、こちらを活用したほうが良いと思います。
詳細は気が向いたら書こうかと思います…書けたらいいな…
Dockerコンテナはデータを保持できない
DockerでMySQLなどのデータベースサーバを運用する場合、データの永続化が問題になります。
Dockerはコンテナを削除すると、保存されたデータが全て消えてしまうためです。
永続化のためにコンテナを作る
データを格納するためだけのData Volume Container(以下ストレージコンテナ)を作成します。
コマンド
$ docker run -d -v /dir/of/data --name storage busybox true
オプションの意味
-
-d
-> コンテナをバックグラウンドで実行する -
-v /dir/of/data
-> ホストにマウントするディレクトリを指定。- この場合コンテナ側のパスのみを指定しているので、ホスト側の
/dir/of/data
は関係がない。 - 例)MySQLのデータディレクトリの場合は、
/var/lib/mysql
- この場合コンテナ側のパスのみを指定しているので、ホスト側の
-
--name storage
-> ストレージコンテナの名前を指定。既存のコンテナと違う名前(ユニーク)なら自由に指定出来る。 -
busybox
-> 使用するイメージ名。-
ubuntu
でも何でもいいが、busybox
は軽量なのでこういう用途にはよく使われる(らしい?)
-
-
true
->busybox
イメージ内で実行するコマンド。- ストレージコンテナはコンテナとして存在しているだけで良いので、何もせずに正常終了する
true
コマンドを使用する。
- ストレージコンテナはコンテナとして存在しているだけで良いので、何もせずに正常終了する
ストレージコンテナを利用するコンテナを作成する
例としてMySQLコンテナを使ってみます。
コマンド
$ docker run -d --volumes-from storage -e MYSQL_ROOT_PASSWORD=root --name mysql_server mysql
オプションの意味
-
-d
-> 同上。 -
--volumes-from storage
-> 先ほど作成したストレージコンテナを指定。これから作成するコンテナにストレージコンテナのディレクトリをマウントする。 -
-e MYSQL_ROOT_PASSWORD=root
-> mysqlイメージで必須のオプション。rootのパスワードを設定します。もちろんrootの部分はお好みで。 -
--name mysql_server
-> 同上。 -
mysql
->mysql
イメージを選択。Dockerは公式でMySQLのイメージがリリースされているようで、こう叩くだけでそのまま使い始められます。すごい。
設定ファイルを追加する
DockerのMySQLイメージは、デフォルトでServer Charset
とDb Charset
がlatin1
になっています。
全部utf8じゃないと気持ち悪い奇病に罹っているの状態の私のように、文字コードなど、設定をいじりたい場合があります。
その場合、ホスト側にある設定ファイルをコンテナの/etc/mysql/conf.d
にマウントしてやればOKです。
コマンド
$ docker run -d --volumes-from storage -v /path/of/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=root --name mysql_server mysql
オプションの意味(重複は割愛)
-
-v /path/of/conf:/etc/mysql/conf.d
-> ホスト側の/path/of/conf
をコンテナの/etc/mysql/conf.d
にマウントします。- こうすることで、ホスト側の
/path/of/conf
の中にcustom.cnf
などを書いておけば、コンテナのMySQLはこれも読みに来てくれます。 - オプションの並び順ですが、イメージ名の前ならば順番は問いません。
- こうすることで、ホスト側の
しかしsaveやexportしてもデータは消える!!
さて、これでストレージコンテナが出来たから、docker save
やdocker export
でデータが持ち運べるゾ〜
と思っていた時期もありました。
なんと、【消えます】。
いくらストレージコンテナといえど、コンテナやイメージのアーカイブにデータは格納されないようです。
それに対し、Dockerの公式ページや、他の方の投稿で多く示されていた方法があったので、それを参考にしました。
バックアップ
$ docker run --rm --volumes-from storage -v $(pwd):/backup busybox tar cvf /backup/backup.tar /dir/of/data
オプションの意味
-
--rm
-> コンテナのプロセスが終了すると、すぐにコンテナが削除されます。- 今回はtarコマンドでアーカイブをするためだけにコンテナを作成するので、それが終われば即・お役御免、ということですね。作られては消される、というのはDockerコンテナの性(さが)でしょうか。
-
--volumes-from storage
-> 同上。 -
-v $(pwd):/backup
-> 現在の作業ディレクトリを、コンテナ側の/backup
にマウントします。-
pwd
は現在の作業ディレクトリを出力するコマンドです。
-
-
busybox
-> イメージ名 -
tar cvf /backup/backup.tar /dir/of/data
-> コンテナで実行するコマンド。- コンテナ内の
/dir/of/data
をアーカイブし、コンテナの/backup
内にbackup.tar
として保存します。- MySQLのデータディレクトリなら
/var/lib/mysql
です。
- MySQLのデータディレクトリなら
- コンテナの
/backup
には上記の通りホストの現在の作業ディレクトリがマウントされているので、ホストの作業ディレクトリにもbackup.tar
が保存されます。 -
tar
コマンドのオプションをzcvf
に、出力ファイル名の拡張子を.tar.gz
にすると、アーカイブに加えて圧縮をかけることが出来ます。
- コンテナ内の
復元
$ docker run --rm --volumes-from new_storage -v $(pwd):/backup busybox cd /dir/of/data && tar xvf /backup/backup.tar
オプションの意味(重複は割愛)
-
--volumes-from new_storage
-> マウントするディレクトリを格納したコンテナ…つまりは、復元するストレージコンテナを指定。 -
cd /dir/of/data && tar xvf /backup/backup.tar
-> コンテナ内の復元先のディレクトリに移動してから、アーカイブを展開する。
つまり・・・どういうことだってばよ?
ストレージコンテナの中身をディレクトリごとアーカイブして外に出してるだけ!
_人人人人人人人人人人人_
> 最早Docker関係ない <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄
しかし、公式サイトにもあるくらいなのでこれが正統なのです。Dockerは「環境を持ち運ぶもの」と考えて、「データを持ち運ぶものではない」と思って使うと、幸せになれるかもしれません。
参考にさせていただいた記事
- Managing data in containers
https://docs.docker.com/userguide/dockervolumes/ - Docker × MySQL
http://qiita.com/baster/items/32a66766cbfd28e63a6b - Dockerのbusyboxは永続コンテナと言いながらexport/saveコマンドでは持ち運びできないよ
http://qiita.com/kumechang/items/fc108b1ec4683f3765d8 - DockerでMySQLを動かす(気を付けるべきところとかいろいろ)
http://qiita.com/TakamiChie/items/a7437b1a24961ba9c83e
追記 2015-09-19 4:08
- tarコマンドの箇所ですが、
busybox
に入っているtar
コマンドはzオプションをつけてgzip圧縮をするのに対応していないようです。busybox
の代わりにubuntu
などを指定するとzオプションでgzip圧縮がかけられます。