Docker でボリュームをマウントする際はホスト側ファイルがコンテナ側ファイルを上書きする

注意

2017/08/05 時点での記事内容です。

具体例

  • 以下のように-vオプションを設定したとします(余計なところは割愛)
  • イメージはUbuntuのイメージとしましょう
  • コンテナ作成時(初回起動時)のオプションです
  • ホスト側の/opt/dataは存在しない(作られていない)とします
-v /opt/data:/etc

この場合、コンテナ側の/etcは「真っ白」になります*1

すなわち

-vオプションによって、ホスト側ディレクトリ:コンテナ側ディレクトリの形式でボリュームのマウントを指定した場合、以下のことが言えます。

  1. 「ホスト側のファイル群」が「コンテナ側のファイル群」を「上書き」する
  2. 「ホスト側でマウントするディレクトリ」が無い場合は自動で生成してくれる*2

コンテナ作成時(初回起動時)に「コンテナ側」→「ホスト側」にファイルをもってくる方法

上記のような仕様ですので、例えばUbuntuのコンテナで、/etc配下を全てホスト側でも編集したい(共有したい)という場合には、予めコンテナ(イメージ)が持っている/etcのファイル群を、コンテナ作成時(初回起動時)にマウントすることが必要です。

となると具体的な手順としては以下のようになるでしょうか。

  1. 「ファイル群を持ってくるだけが目的のコンテナ」を作る
  2. 上記コンテナから/etcのファイル群を根こそぎホスト側にコピーする*3
  3. 「1.」のコンテナは破壊する
  4. 「2.」のファイル群をホスト側にマウントして、新たにコンテナを作る

これで理論上はいけます。

どう考えてもイケてない

しかしこの方法はあまりに煩雑すぎます。Docker 側でこのようなことをやってくれるオプションがあったり、今後のバージョンアップ予定でそのようなオプションがついたりするのでしょうか。私が知らないだけでしょうか。

いや、そもそもこのような利用方法を Docker は想定していない可能性もあります。ここらへんは私の知識不足なので不明な点が多々あります。

一部のイメージでは上記方法を採らなくても大丈夫

例えばMySQLのイメージですと、-v /opt/mysql_data:/var/lib/mysqlとコンテナ作成時に指定しても/opt/mysql_dataにちゃんとデータが反映されています。一度ファイル群のデータをホスト側に反映させられていれば、以降はそれをホスト側からコンテナ側に上書きして永続化が図れます*4

MySQLのイメージがこのような動作をするのは、内部的にそうなるような動作のイメージファイルだからです(と思います。あるいは MySQL 自体の動作仕様によるもの)。なのでこれを一般化するのはマズいです*5

まとめ

データの永続化を考えて-vオプションを使う場合は上記のことを意識していないと永続化ができないことがあります。特に自前で作成するイメージでは注意ですね。

補足

このことについては今まであいまいな理解しかしていなかったのですが、やはり実際に手を動かして自分で体験しないと分からないし、身につかないですね。時間はかかってしまいますが。

参考ページ

以下のページを参考にさせて頂きました。感謝です。

コンテナでデータを管理する — Docker-docs-ja 1.9.0b ドキュメント

*1:厳密には違うが、原則として

*2:中身は空っぽ

*3:「docker cp」コマンド

*4:というかそうでないと「永続化」ではない

*5:これを混同していたため今まで理解が半端でした

Powered by はてなブログ