Docker の Volumes と Bind mounts


Docker の Volumes と Bind mounts について、何度読んでも意味が分からないのでまとめる。

docker run コマンドの -v (--volume) オプション

リファレンス: https://docs.docker.com/engine/reference/run/#volume-shared-filesystems

-v, --volume=[host-src:]container-dest[:]

The host-src can either be an absolute path or a name value. If you supply an absolute path for the host-src, Docker bind-mounts to the path you specify. If you supply a name, Docker creates a named volume by that name.

Docker 内のファイルを共有するには、Volumes と Bind mounts という二つの方法があるが、ややこしいことに、同じオプションで Volumes と Bind mounts という異なる機能を設定する。

A name value must start with an alphanumeric character, followed by a-z0-9, _ (underscore), . (period) or - (hyphen). An absolute path starts with a / (forward slash).

  • host-src が英数文字から始まる時: Volumes
  • host-src が / から始まる時: Bind mounts

Volumes https://docs.docker.com/storage/volumes/

Volume を作る

$ docker volume create my-vol

Volume のリスト。いつの間にか出来ているボリュームの最後に先程作った物が出る。

$ docker volume ls
DRIVER    VOLUME NAME
local     0ac8a1264245c3d065e045e06f5509691df967bba733deb49052548a04c39c5e
...
local     my-vol

Volume の情報を見る。

$ docker volume inspect my-vol
[
    {
        "CreatedAt": "2021-09-16T01:41:33Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
        "Name": "my-vol",
        "Options": {},
        "Scope": "local"
    }
]

これを見ると /var/lib/docker/volumes/my-vol/_data に実体がありそうだが、ホストが Mac だと見えない。この Volume をマウントして cont1 と名付けたコンテナを動かし、hello ファイルを作る。

$ docker run --name cont1 -v my-vol:/my-vol ubuntu \
  bash -c 'echo "Hello, world!" > /my-vol/hello'

Volume を別の cont2 と名付けたコンテナにマウントして中を見る。

$ docker run --name cont2 -v my-vol:/my-vol ubuntu \
  cat /my-vol/hello
Hello, world!

ちゃんと共有されている。

Bind mounts https://docs.docker.com/storage/bind-mounts/

Volumes を使うとホストのどこにファイルが保存されるか分からない。ホスト側の位置を指定したい時は Bind mounts を使う。

例えば cont1 で先程作った ファイルをホストにバックアップする時はこうする。

$ mkdir backup
$ docker run --rm --volumes-from cont1 -v $PWD/backup:/backup ubuntu \
  tar cvf /backup/backup.tar /my-vol
tar: Removing leading `/' from member names
/my-vol/
/my-vol/hello

次の事が起こる。

  • --volumes-from cont1: cont1 コンテナに使われた Volumes を全部マウントする。
  • -v $PWD/backup:/backup: ホストの $PWD/backup をコンテナの /backup に bind mounts する。
  • tar cvf /backup/backup.tar /my-vol: コンテナの /my-vol を /backup/backup.tar にバックアップする。
  • コンテナの /backup/backup.tar の実体はホストの $PWD/backup:/backup/backup.tar なので、コマンドが終わるとホストに backup.tar が残る。

確認

$ tar tf backup/backup.tar
my-vol/
my-vol/hello

後片付け

$ docker container rm cont1 cont2
$ docker volume prune