Dockerにおけるvolumeを使用したデータ管理(個人的備忘録)

## Dockerにおけるデータ管理の概要
コンテナで扱う動的なデータは、起動中のコンテナの読み書き可能なレイヤー内に置くこともできるが、いくつかのデメリットがある。例えばコンテナが削除された時点で、コンテナ内のデータも消える。コンテナ間で共有することもできない。書き込みのパフォーマンスもホスト上のデータに書き込むのに比べて、書き込みのパフォーマンスが良くない。

##volumeを使用したデータ管理
###Linuxの場合
/var/lib/docker/volumes配下に作成される。これが自動的にコンテナにマウントされる。作成されたvolumeは名前を付けて管理することができ、複数のコンテナにマウントすることができる。また、複数のコンテナで共通のファイルを読み書きすることができる。volumeはコンテナが削除されても消えず、明示的に削除されるまで消えない。ファイルの移動は推奨されていないため、コンテナ上でファイルを管理するために用意されている機能。

##基本的なvolumeの管理コマンド
```haml
-# 環境の差異を避けるためdocker-machineコマンドで仮想マシンを起動してその中で作業をする。
% docker-machine create vol-test
-# 作成したホストにssh接続
% docker-machine ssh vol-test
-# docker volume create 新しいvolume名
$ docker volume create my-vol
-# 存在するvolumeの確認
$ docker volume ls
-# Dockerで管理されるホストマシン上の領域に「my-vol」と言うvolumeが作成される。
DRIVER              VOLUME NAME
local               my-vol
```

## volumeの詳細確認
```haml
-# docker valume inspect volume名
$ docker valume inspect my-vol
```
## volumeの削除
```haml
-# docker valume rm volume名
$ docker valume rm my-vol
```

## コンテナにvolumeをマウントする。
###-vによるマウント
```haml
-# docker run -itd --name コンテナ名 -v volume名:マウントポイント コンテナ元
$ docker run -itd —-name mount-c1 -v vol1:/app nginx:latest
```
-vの引数にコロン区切りでvolume名とコンテナ上にマウントするパスを指定する。今回は**「vol1」** というvolume名で、存在しないので新規のvolumeとして作成される。コンテナ内のマウントポイントは**「/app」**になる。docker volume lsコマンドで「vol1」が作成されているのがわかる。docker inspectコマンドでコンテナの詳細を確認することで、マウントされているvolumeを確認することができる。

##コンテナに接続してvolumeの情報を確認する。
```haml
$ docker exec -it mount-c1 /bin/bash
# df
Filesystem     1K-blocks   Used Available Use% Mounted on
overlay         18714000 189496  17535376   2% /
tmpfs              65536      0     65536   0% /dev
tmpfs             504516      0    504516   0% /sys/fs/cgroup
shm                65536      0     65536   0% /dev/shm
/dev/sda1       18714000 189496  17535376   2% /app
tmpfs             504516      0    504516   0% /proc/asound
tmpfs             504516      0    504516   0% /proc/acpi
tmpfs             504516      0    504516   0% /proc/scsi
tmpfs             504516      0    504516   0% /sys/firmware
```
「/app」がマウントされているのがわかる。

##/appにファイルをupしてみる
```haml
-# appに移動
# cd app
-# 「hogehoge」ファイルの作成
# touch hogehoge
# ls
hogehoge
```

## 別のコンテナに「mount-c1」をマウントし同じファイルがあるか確認する。
###--mountでマウントする。
```haml
-# docker run -itd --name コンテナ名 --mount source=volume名,target=マウントポイント コンテナ元
$ docker run -itd —-name mount-c2 —-mount source=vol1,target=/app nginx:latest
```
--mountでマウントする場合、マウント元のvolumeをsourceの引数に指定し、マウント先をtargetの引数に指定する。動作は-vと同様。

```
$ docker exec -it mount-c2 /bin/bash
# ls -l /app
```
Hogehogeファイルが確認できる。このように同じvolumeを複数のコンテナにマウントすることで、ファイルを共有することができる。ただし、この方法で共有できるのは、同じホスト内で実行しているコンテナのみで、異なるホスト間で共有することができない。

##コンテナ起動時のvolumeのマウント
```haml
-# docker run -itd --name コンテナ名 --mount source=valume名,destination=マウントポイント コンテナ元
$ docker run -itd —-name mount-c3 —-mount source=copy-vol,destination=/etc/nginx nginx
```
「copy-vol」というvolumeが作成され、「/etc/nginx」にマウントされた。volume内に「etc/nginx」の設定ファイルやディレクトリがcopyされている。

```haml
$ docker volume inspect copy-vol
```
Volumeの詳細を見るとマウントポイントが確認できる。新規にvolumeが作成されマウントされた場合は、既に存在していたファイル類がコピーされ、volume上に存在するようになる。マウントのもう一つのパターンとして、既に存在するvolumeをマウントする場合がある。コンテナ上のファイルがコピーされることはない。あくまで既存のvolumeが指定したマウントポイントにマウントされ、コンテナ上に存在していた既存のファイル類はマウントvolumeによって隠れて見えない状態になる。

##読み取り専用でvolumeをマウントする方法
コンテナごとに読み書き可能にするか、読み取り専用にするかを設定することができる。マウントフラグを使用して読み取り専用としてマウントする方法。

```haml
-# docker run -itd --name コンテナ名 --mount source=volume名,destination=マウントポイント,readonly コンテナ元
$ docker run -itd —-name mount-c4 -—mount source=copy-vol,destination=/etc/nginx,readonly nginx
```
「,」カンマ区切りで「readonly」と指定する。

```
$ docker inspect mount-c4
```
"Mounts”の"RW": falseになっていることが確認できる。

##-vでの読み取り専用でvolumeをマウントする方法
```haml
-# docker run -itd --name コンテナ名 -v volume名:マウントポイント:ro コンテナ元
$ docker run -itd —-name mount-c5 -v copy-vol:/etc/nginx:ro nginx
```
volume名:マウントポイント:roとすることで、読み取り専用に設定することができる。