Docker Volume の上書きについて


前提

  • 本記事執筆時の Docker 最新バージョン: 19.03
  • 書いている人は、業務で本格的に docker を使ったりしておらず、個人開発で適当に使っていたが、よくわからず使っている部分もあったので改めて調べてるレベル。

悩み

前回 Docker Volume について調べてボリューム完全に理解したと思いながら構築していました。
しかし、単一ボリュームを複数コンテナのディレクトリにマウントする際に、元々コンテナのディレクトリにおいてあったファイルが上書きされたりする挙動を理解していないことに気づき、ちゃんと知っとかないとふとした時にデータ消去とかになったら怖いなと思った次第です。

結論

  • マウントするボリュームに何かしらファイルやディレクトリが存在すれば、マウントされるコンテナ側のディレクトリの中身は全部上書きされる。
  • マウントするボリュームに何も入っていなくて、マウントされるコンテナ側のディレクトリに何か入っていれば、ボリュームにコピーされる。

以上です。シンプル。
以下は実際に上記を確かめてるだけなので、結論以上の情報はないです。

試してみる

適当にデータの入ったディレクトリのあるコンテナを2つつくり、それぞれ同じボリュームをそのディレクトリにマウントするように Compose で立ち上げてみて、ボリュームの中身がどうなるか見てみました。

以下のような感じでファイルを用意しました。

volume_test
├── Dockerfile-vol01
├── Dockerfile-vol02
├── docker-compose.yml
├── vol01
    └── file01
└── vol02
    └── file02

まず適当にデータを入れたディレクトリだけがあるイメージを作ります。(vol02 は数字変えただけなので省略)

Dockerfile-vol01
FROM ubuntu:latest

COPY vol01 /vol01

CMD ["bin/sh"]

$ docker image build -f Dockerfile-vol01 -t hoge/volcontainer01:latest .

そして Compose で2つのコンテナを立ち上げ、データが入ったディレクトリそれぞれに、単一のボリューム(voltest)をマウントします。

docker-compose.yml
version: "3"

services:
  vol01:
    image: hoge/volcontainer01:latest
    container_name: volcontainer01
    tty: true
    volumes:
      - voltest:/vol01

  vol02:
    image: hoge/volcontainer02:latest
    container_name: volcontainer02
    tty: true
    volumes:
      - voltest:/vol02

volumes:
  voltest:
    driver: local
$ docker-compose up -d

この時、voltestの中身はどうなっているのか。

$ docker container exec -it volcontainer01 ls vol01
file01

file01 だけが入っており、vol02の方に入っていたfile02は入っていません。
これは流れ的には、volcontainer01が立ち上がった時にvoltestボリュームが生成され、vol01に入っていた内容がコピーされます。
その後volcontainer02が立ち上がってvol02voltestボリュームがマウントされる際に、voltestにはすでにファイルが存在するので、vol02の中身をまるごと上書きしているということです。

ちなみにこの時、もしvol01に何も入っておらず、vol02にだけファイルが入っていた場合は、vol02にマウントする時点で中身がコピーされるため、voltestにはfile02が入った状態になります。

では試しに、このままvoltestの内容を変更してから Compose を削除し、再度立ち上げてみましょう。

$ docker container exec -it volcontainer01 rm vol01/file01
$ docker container exec -it volcontainer01 touch vol01/addfile
$ docker-compose down
$ docker-compose up -d

この時、voltestの中身はこうなっています。

$ docker container exec -it volcontainer01 ls vol01
addfile

ボリュームはデータの永続化のための仕組みなのでコンテナが破棄されても残ります。
再度 Compose でコンテナを立ち上げると、今度はvoltestには既に先程入れたファイルが存在しており、vol01の内容もvol02の内容も上書きしてしまうためです。

ということで、繰り返しになりますが、

  • マウントするボリュームに何かしらファイルやディレクトリが存在すれば、マウントされるコンテナ側のディレクトリの中身は全部上書きされる。
  • マウントするボリュームに何も入っていなくて、マウントされるコンテナ側のディレクトリに何か入っていれば、ボリュームにコピーされる。

ということが確認できました。

参考文献