Dockerにボリュームについて調べた


- Dockerのファイル管理方法をあらためて調べた。
    - [ボリュームの利用](https://matsuand.github.io/docs.docker.jp.onthefly/storage/volumes/)
    - [バインドマウントの利用](https://matsuand.github.io/docs.docker.jp.onthefly/storage/bind-mounts/)

- 動作確認対象のDocker Engine のバージョンは「 Version: 19.03.12」

# Dockerでファイルを管理する方法

- 以下の3種類

## ボリューム

- Dockerが管理する領域にファイルを永続化する方法

- バインドマウントよりも優れている点が多く、ファイルを永続化する際の第1案

    [バインドマウントの利用](https://matsuand.github.io/docs.docker.jp.onthefly/storage/bind-mounts/)より
 
    > 今から新たに Docker アプリケーションを開発しようとする場合は、これにかわって 名前つきボリューム の利用を考えてみてください。

- Docker CLI で操作できる

- リモートホストにファイルを保存したり、暗号化して保存することもできる

## バインドマウント

- Dockerが稼働するホスト上の任意のディレクトリにファイルを永続化する方法

- Docker CLI で操作できない

- Dockerが動作するホスト上にしかファイルを保存できない


## tmpfs

- 一時的な情報を保存する方法

- コンテナを削除するとファイルは消える

# `-v` ( `--volume` ) と `--mount` の違い

- コンテナのファイル管理方法を指定するオプション。書式が異なる

- `--mount`の方が設定内容がよりわかりやすく、推奨

    [バインドマウントの利用](https://matsuand.github.io/docs.docker.jp.onthefly/storage/bind-mounts/)より

    > はじめて利用する方は--mountを利用してください。 

## `-v`, `--volumne` で指定する場合

- オプションを`:`で区切って、1行で記載する。

```
<マウント対象>:<コンテナのディレクトリパス>:<オプション>
```

### マウント対象

- ボリュームとバインドマウントで意味合いが違う。

- ボリュームの場合、名前付ボリュームの場合の名前。
省略可能で、その場合、匿名ボリュームを指定したものとして扱われる。

- バインドマウントの場合の場合、ファイルをマウントする__ホストサーバー__のディレクトリのパス。
ホスト上にディレクトリが存在しない場合、__自動で作成される__ ( `--mount`で指定する場合と挙動が異なる )

### コンテナのディレクトリ

- ファイルをマウントする__コンテナ__のディレクトリパス

### オプション

- `private`または`ro`を指定した場合、読み取り専用扱いとなる


## `--mount` で指定する場合

- `<key> = <value>`形式で記載する。`key`の一覧は以下

### type

- マウントの種類
- 指定可能な値は`bind`(バインドマウントの場合),  `volume`(ボリュームの場合),  `tmpfs`(一時的な保存)のいずれか

### source

- ボリュームの場合、名前付きボリュームの名前。省略した場合は匿名ボリュームとして扱われる
- バインドマウントの場合、ホスト上のファイルまたはディレクトリのパス
- キー名は、`src`でもOK
- ディレクトリが存在しない場合、__エラーとなり起動できない__ ( `-v`、または `--volume`との違い )

### destination

- コンテナ上でマウントするファイルまたはディレクトリのパス
- キー名は、`dest`, `target`でもOK

### readonly

- 読み取り専用

----
## 動作確認

- `service`として`app`を作る
- `app`は2つのボリュームを利用
- `storage1`はボリューム。`storage2`はバインドマウント

```
services:
  app:
    volumes:
      - storage1:/storage1
      - /storage2:/storage2:ro

volumes:
  storage1:
```

この状態でdocker-compose を実行し、

```
docker-compose up -d
```

以下のコマンドにより、ボリュームを確認する

```
docker volume ls
```

以下の結果が返ってきて、ボリュームが作成されている事が確認できる

```
$ docker volume ls
DRIVER              VOLUME NAME
local               <プロジェクト名>_storage1
```

VOLUME_NAMEは自動で生成した名前が設定される。DRIVERはデフォルトの`local`が設定されている。

細かな内容を見たい場合は、docker inspect で確認できる。

```
docker inspect <プロジェクト名>_storage1
```

以下の結果が得られ、作成したボリュームのファイルが格納されているディレクトリ等が確認できる

```
$ docker inspect <プロジェクト名>_storage1
[
    {
        "CreatedAt": "20XX-XX-XXTXX:XX:XXZ",
        "Driver": "local",
        "Labels": {
            "com.docker.compose.project": "<プロジェクト名>",
            "com.docker.compose.version": "<バージョン番号>",
            "com.docker.compose.volume": "storage1"
        },
        "Mountpoint": "/mnt/sda1/var/lib/docker/volumes/<プロジェクト名>_storage1/_data",
        "Name": "<プロジェクト名>_storage1",
        "Options": null,
        "Scope": "local"
    }
]
```

次に、起動されたコンテナに対して以下のコマンドを実行する

```
docker inspect <コンテナのID>
```

以下の結果が得られ、コンテナにボリューム(storage1)とバインドマウント(storage2)の設定がされている

```
$ docker inspect <コンテナのID>
：
略
：
"Mounts": [
            {
                "Type": "bind",
                "Source": "/storage2",
                "Destination": "/storage2",
                "Mode": "ro",
                "RW": false,
                "Propagation": "rprivate"
            },
            {
                "Type": "volume",
                "Name": "<プロジェクト名>_storage1",
                "Source": "/mnt/sda1/var/lib/docker/volumes/<プロジェクト名>_storage1/_data",
                "Destination": "/storage1",
                "Driver": "local",
                "Mode": "rw",
                "RW": true,
                "Propagation": ""
            }
        ],
```

---

以上です！ 誤りなどあれば指摘をいただけるとありがたいです！