Dockerにおけるデータ管理

## はじめに
こちらはDockerにおけるデータ管理についての記事になります。情報が陳腐化している箇所もありますのでご了承ください:bow:。

以下は、私がDocker関連についてまとめている記事になります。もし興味がありましたらご覧になってください。
* [Dockerにおけるコンテナ](https://qiita.com/Hirohana/items/c881118021fd156ccefe "Dockerにおけるコンテナ") 
* [Dockerにおけるイメージとは](https://qiita.com/Hirohana/items/a7b11c72e525c48d34bf "Dockerにおけるイメージとは") 
* [Dockerにおけるネットワーク](https://qiita.com/Hirohana/items/3fff1a1d11a0f1505dad "Dockerにおけるネットワーク") 
* [Dockerにおけるデータ管理](https://qiita.com/Hirohana/items/59a22d549fcfb096f0b9 "Dockerにおけるデータ管理")

最初にDockerにおいて、コンテナ内のデータをPC（ホスト）のファイルシステムに紐付けることができる`マウント`という用語について確認したいと思います。

## マウントとは
:::note Dockerにおけるマウントとは
ホストマシンのディレクトリやファイルシステムをDockerコンテナに接続して、利用可能な状態にすることを指します。
:::

Dockerコンテナ内に格納されたデータは、コンテナを停止しても消えることはありませんが、コンテナを削除した場合にはデータも併せて消えてしまいます。

Dockerのマウント機能を利用すると、コンテナ内のデータをPC（ホスト）のファイルシステムに紐付けることができるようになるため、コンテナの作成・削除を繰り返すライフサイクルと切り離して、データを永続的に管理できるようになります。

## Dockerに記憶領域をマウントする3つの方法

Dockerコンテナ内で生成されたデータを永続化するためには、ホストマシンとのデータの共有が必要です。Dockerにおけるデータの共有には以下3つの方法が挙げられます。

1. **ボリュームマウント**
1. **バインドマウント**
1. **tmpfs(一時メモリ)マウント**

では最初に`ボリュームマウント`について解説していきます。

## ボリュームマウント

:::note info
Dockerによって管理されているホストファイルシステム上の一部に保管し、コンテナにマウントすることです。
:::

![スクリーンショット (251).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1220815/f8f243e4-27a4-f4b7-f56e-6c28c276505d.png)

ボリュームマウントのメリットには以下が挙げられます。

* Dockerが提供するデータ管理機能を利用するため、コンテナの移動やバックアップの際に便利です。
* データの永続性が保証され、コンテナの再作成や更新時にデータが保持されます。
* 複数のコンテナ間で同じボリュームを共有できるため、データの共有が容易です。

:::note warn
**ボリュームの注意点について**
それは、マウントしたデータの編集方法に制約がある点です。ボリュームマウントは、コンテナを経由せずに直接ボリュームにアクセスすることができません。そのため、マウントしたファイルを編集する場合、コンテナを経由して編集する前提となります。
:::

:::note info 
**コンテナ起動時のボリュームマウントの動作について**
1. まだ存在しないボリューム名を使用して、マウントした場合かつ、マウントポイントのディレクトリにファイルが存在しない場合は空のボリュームが作成され、マウントした時点で中身が空の状態になります。
2. もう1つのパターンがまだ存在しないボリューム名を使用して、マウントした場合かつ、マウントポイントのディレクトリに既にディレクトリやファイルが存在する場合は、作成されたボリュームにコンテナ上に存在しているディレクトリやファイルがコピーされます。
:::

以下に、ボリューム関連のコマンドについて説明していきます。

### ボリューム作成

Dockerのボリュームを作成するコマンドは`docker volume create <ボリューム名>`になります。
```terminal: terminal
$ docker volume create my-vol
```

### ボリュームの一覧を表示

`my-vol`というボリュームが作成されたかどうかを確認するには`docker volume ls`コマンドを使います。
```terminal: terminal
$ docker volume ls
DRIVER    VOLUME NAME
local     my-vol
```

### ボリュームの詳細情報を表示

また、`my-vol`がどこに存在するかを確認するには`docker volume inspect <ボリューム名>`コマンドを使います。

```terminal: teminal
$ docker volume inspect my-vol

[
    {
        "CreatedAt": "2023-06-26T04:54:52Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
        "Name": "my-vol",
        "Options": null,
        "Scope": "local"
    }
]
```

上記を見ると、`"Mountpoint": "/var/lib/docker/volumes/my-vol/_data",`と記載されており、`my-vol`ボリュームが`/var/lib/docker/volumes/my-vol/_data`に作成されていることが確認できました。

### ボリュームをマウントする方法
ボリュームをマウントするには`-v`オプションを使ってコンテナを起動する必要があります。
```terminal: terminal
$ docker run -itd --name mount-c1 -v vol1:/app nginx:latest

$ docker inspect mount mount-c1

// 省略
 "Mounts": [
            {
                "Type": "volume",
                "Name": "vol1",
                "Source": "/var/lib/docker/volumes/vol1/_data",
                "Destination": "/app",
                "Driver": "local",
                "Mode": "z",
                "RW": true,
                "Propagation": ""
            }
        ],
// 省略
```

### ボリュームの削除

ボリュームの削除には`docker volume rm <ボリューム名>`コマンドを使用します。
```terminal: terminal
$ docker volume rm my-vol
```

### マウントされていないボリュームを全て削除
マウントしていないボリュームを一括削除する場合、以下のコマンドを実行します。
```terminal: terminal
$ docker volume prune
```

## バインドマウント
:::note info
Docker Engineの管理下にない既存ディレクトリ（デスクトップやドキュメント等）をコンテナにマウントすることをバインドマウントと呼びます。
:::

![スクリーンショット (252).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1220815/13b7f9dd-5894-a214-bf09-fbaa439338dd.png)

バインドマウントを使用すると、コンテナ内の変更はホストマシンのファイルシステムに直接反映され、同様にホストマシン側の変更もコンテナに反映されます。これにより、コンテナ内外でのデータの共有や永続化が可能になります。

バインドマウントを使用するには、-vオプションを使用してコンテナのディレクトリとホストマシンのディレクトリを指定します。
```terminal: terminal
$  docker run -itd --name bind-test -v "$(pwd)"/source:/app nginx
```

## tmpfs(一時メモリ)マウント
:::note info
Linuxにおいて一時的なファイルシステムをメモリ上に作成するための仕組みです。tmpfsを使用すると、メモリ上にファイルシステムを作成し、データの読み書きを高速に行うことができます。
:::

![スクリーンショット (253).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1220815/e3d4e93a-daef-7eb3-a51e-b4a67cf83527.png)

tmpfsは、一時ファイルや一時データを格納するために使用されることが一般的です。例えば、一時ファイル、一時的なキャッシュデータ、ログファイルなど、一時的なデータを効率的に処理する際に利用されます。

ただ、コンテナの再起動やホストの再起動によって、データが失われることにも注意する必要があります。

tmpfsオプションを使用してtmpfsをマウントすることができます。以下は、Dockerコマンドでtmpfsをマウントする例です。
```terminal: terminal
$ docker run -d --name tempf-test --tmpfs /tmp -p 8080:80 nginx
```
## 終わりに
最後まで記事をご覧いただきありがとうございました。

間違い等ありましたらご指摘いただけると幸いです:bow:

## 参考

https://docs.docker.jp/storage/tmpfs.html