【Docker Storage】ボリュームで MySQL コンテナのデータが消えないようにする

# はじめに
この記事では、Docker のボリューム機能を利用して、コンテナを削除してもコンテナのデータが消えないようにする手順について記載します。
ボリュームへの理解促進の一環で行っています。

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

# 開発環境
開発環境は以下の通りです。

- Windows 11
- Docker Engine 26.1.1
- MySQL 8.4.0

# ボリュームを作成する
まずは、`docker volume create` でボリュームを作成します。

https://docs.docker.com/reference/cli/docker/volume/create/

```powershell
docker volume create --name my-volume
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/4343ba26-c89b-0926-a97e-8137979c9cd2.png)

`docker volume ls` で作成したボリュームを確認します。

https://docs.docker.com/reference/cli/docker/volume/ls/

```powershell
docker volume ls
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/e2fe0507-8bf1-51bc-78b8-92de566cd214.png)

# MySQL コンテナ起動時にボリュームをマウントする
`docker container run` コマンドの `--mount` オプションを指定して、作成したボリュームをコンテナにマウントします。

https://docs.docker.com/reference/cli/docker/container/run/#mount

`--mount` オプションには、`<key> <value>` 形式の設定をカンマ区切りで指定します。

| \<key> | \<value> | 備考 |
|---|---|---|
| type | volume |  |
| source | my-volume | マウント元 |
| target | /var/lib/mysql | マウント先 |

:::note
マウント先の `/var/lib/mysql` は、MySQL サーバーがデータを保存するデフォルトのディレクトリになります。MySQL 設定ファイル（`/etc/my.cnf`）で定義されています。

```powershell
docker container run --rm mysql:8.4.0 cat /etc/my.cnf
```

```powershell
[mysqld]
...
datadir=/var/lib/mysql
...
```
:::

それでは、ボリュームをマウントして MySQL コンテナを起動します。

```powershell
# docker container run [OPTIONS] IMAGE [COMMAND] [ARG...]
docker container run                                            `
--name db1                                                      `
--rm                                                            `
--detach                                                        `
--env MYSQL_ROOT_PASSWORD=password                              `
--env MYSQL_DATABASE=sample                                     `
--publish 3306:3306                                             `
--mount type=volume,source=my-volume,target=/var/lib/mysql `
mysql:8.4.0
```

MySQL サーバーに接続します。

```powershell
mysql --host=127.0.0.1 --port=3306 --user=root --password=password sample
```

user テーブルを作成し、Wyatt と Billy を user テーブルに追加します。

```mysql
create table user (id int, name varchar(32));
```

```mysql
insert into user (id, name) values (1, 'Wyatt');
```

```mysql
insert into user (id, name) values (2, 'Billy');
```

```mysql
select * from user;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/a348cd1b-94a7-8780-8a5c-d32394336f2e.png)

これで MySQL サーバーにデータが作成され、`/var/lib/mysql` に保存されました。`/var/lib/mysql` はボリュームがマウントしてあるので、コンテナ内のディレクトリではなく、ボリュームにデータが保存されています。

# 動作確認
動作確認のため、db1 コンテナを停止します。

```powershell
docker container stop db1
```

新たに db2 コンテナを起動します。db1 コンテナにマウントした `my-volume` を同じように db2 コンテナにマウントします。

```powershell
docker container run                                            `
--name db2                                                      `
--rm                                                            `
--detach                                                        `
--publish 3306:3306                                             `
--mount type=volume,source=my-volume,target=/var/lib/mysql `
mysql:8.4.0
```

:::note
db2 コンテナの起動に環境変数は不要です。コンテナ起動時に環境変数のデータを元に MySQL サーバーのデータが作成されます。今回はボリュームを利用するので、データは既に作成済みです。
:::

MySQL サーバーに接続します。

```powershell
mysql --host=127.0.0.1 --port=3306 --user=root --password=password sample
```

db2 コンテナの user テーブルに Wyatt と Billy が確認できます。

```mysql
select * from user;
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318188/d6ed4da5-7217-b9eb-e708-dc47931b54f1.png)

# 参考
- [docker container run](https://docs.docker.com/reference/cli/docker/container/run/)
- [docker volume create](https://docs.docker.com/reference/cli/docker/volume/create/)
- [docker volume ls](https://docs.docker.com/reference/cli/docker/volume/ls/)
- [Volumes](https://docs.docker.com/storage/volumes/)
- [	鈴木亮「開発系エンジニアのためのDocker絵とき入門」秀和システム、2024](https://www.shuwasystem.co.jp/book/9784798071503.html)

# 関連記事

https://qiita.com/Yasushi-Mo/items/678fefffbf4807c83d44