コンテナでMySQL環境作成

# 目的
データベースのお勉強をしたい際に気軽に作って壊してやりたい放題の環境が欲しいときってありますよね。
そんな時はコンテナ環境を使うのがおすすめです。

今回はコンテナにMySQLを入れ、Workbenchから接続するまでの手順をサクッと解説していきます。

# 使うもの
・Docker
・Docker Compose
・MySQL Workbench

それぞれのインストール手順等は省きます。

# 構築
## docker-compose.yml
早速docker-compose.ymlファイルを作成します。

```yml:docker-compose.yml
# Composeファイル形式
version: '3'

# Dockerの中にボリュームというデータを保持する領域を確保する。（任意の名称でOK）
volumes:
  learn-db-data:
  
services:
  db:
    # 使用イメージを指定する。（今回はDockerが公式に用意していくれているMySQLのイメージを利用）
    # https://hub.docker.com/_/mysql
    image: mysql:8.0.23
    # 作成されるコンテナ名を指定する（任意の名称でOK）
    container_name: learn-db
    # データを永続化するためにDockerのリソースと紐づける
    volumes:
      - 'learn-db-data:/var/lib/mysql'
    # ホスト上にコンテナのポートを割り当てる。ホスト:コンテナ
    ports:
      - '3307:3306'
    # コンテナ内の環境変数を指定する。
    # MySQLのルートユーザー、初期DB及び初期ユーザーの指定も可能。
    environment:
      # rootユーザーのパスワードを指定する。（必須）
      - 'MYSQL_ROOT_PASSWORD=root'
      # 初期作成されるDB名を指定する。（任意）
      - 'MYSQL_DATABASE=sample-db'
      # 作成されるユーザー名を指定する。（任意）
      - 'MYSQL_USER=user'
      # ユーザーのパスワードを指定する。（任意）
      - 'MYSQL_PASSWORD=user'
      # タイムゾーンを指定する。（任意）
      - 'TZ=Asia/Tokyo'
```


ymlファイルの各項目についてはコード内のコメントを参考にしてください。

## 起動
ymlファイルが準備できたら下記コマンドでビルドを行います。
```
> docker-compose up -d --build
[+] Running 3/3
 - Network learn-mysql_default         Created                                                             0.0s
 - Volume "learn-mysql_learn-db-data"  Created                                                             0.0s
 - Container learn-db                  Started                                                             0.9s
```

無事ビルドが完了したらコンテナが出来上がっていると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621838/619e6be3-c1c6-228d-2f58-32a9b5b3f2a0.png)
作成しました。
## MySQL WorkbenchからコンテナのDBへ接続
Workbenchから新規接続を行います。
ここでの設定内容は`Docker-compose.yml`ファイルに定義した内容を入力します
| 項目 | 値 |
|:-:|:-:|
| Connection Name | 任意の名称 |
| Connection Method | Standard(TCP/IP) |
| Hostname | ホストマシンのIPアドレス |
| Port | ymlファイルで定義したホスト側のポート番号 |
| Username | ymlファイルで定義したMySQLのユーザー名 |
| Password | ymlファイルで定義したMySQLのユーザーのパスワード |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621838/4ca87224-ee41-4cfb-c9b7-78e161dc4836.png)

接続が成功すると、まだ空っぽのDBが見れましたね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621838/e76ff32e-1218-5ef4-6edb-d017f916742b.png)

以上がコンテナでMysql環境の構築手順になります。
コンテナ内のデータはDockerのリソースと紐づけて永続化しているので、コンテナを削除しても再度コンテナを作れば簡単に復元できます。


# 知っておくと便利なこと
## MySQLの設定方法
コンテナ内のデータは永続化しているといいましたが、設定情報などは別途行う必要があります。
ただ、毎度毎度コンテナを作り直すたびに設定しなおすのはスマートではないですよね。
そこで知っておきたい知識として、コンテナのMySQLに設定情報を反映させる方法を記載します。

任意の場所に`my.cnf`ファイルを作成し、MySQLに設定したい内容を記述します。
今回は`Docker-compose.yml`ファイルと同階層に`conf.d/my.cnf`を作成しました。

```:my.cnf
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_0900_ai_ci
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
default_authentication_plugin=mysql_native_password

[client]
default-character-set=utf8mb4
```

`Docker-compose.yml`ファイルのVolumeを追記します。
```yml:Docker-compose.yml
services:
  db:
    # 省略
    volumes:
      - 'learn-db-data:/var/lib/mysql'
      - './conf.d/my.cnf:/etc/mysql/conf.d/my.cnf' # <------------追加
    # 省略
```

こうすることによって、コンテナが作成される際にホスト側で用意した設定ファイルをコンテナ内のMySQLに反映させることができます。

:::note warn
my.cnfファイルは読み取り専用である必要があります。ご注意ください！！！
:::

## 初期データ登録方法
ymlファイルで初期作成されるデータベースまで定義はできました。
しかし、データベース作成と同時に初期データまでをあらかじめ登録したい場合があるかと思います。
その際に役立つ手順を記載します。

まず任意の場所にフォルダを作成し、その中に初期登録用sqlファイルを格納してください。
今回は`Docker-compose.yml`ファイルと同階層に`initdb.d/001_init.sql`を作成しました。
`001_init.sql`の中身はシンプルに1つテーブルを作成するものになります。

```sql:001_init.sql
CREATE TABLE `user`(
    id INT AUTO_INCREMENT NOT NULL, 
    name VARCHAR(30) NOT NULL ,
    age INT NOT NULL,
    PRIMARY KEY (id));
```

`Docker-compose.yml`ファイルのVolumeを追記します。
```yml:Docker-compose.yml
services:
  db:
    # 省略
    volumes:
      - 'learn-db-data:/var/lib/mysql'
      - './conf.d/my.cnf:/etc/mysql/conf.d/my.cnf'
      - './initdb.d:/docker-entrypoint-initdb.d' # <------------追加
    # 省略
```

以上の設定まで行えたら、改めて`docker-compose up -d --build`を実行してコンテナを作成してみてください。
データベース、テーブル、設定と必要なもの全てがそろった環境が一瞬で構築されたかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/621838/c705fb9f-f073-4716-3cd5-b79740b0c503.png)


# まとめ
Dockerは1度使い方を覚えてしまえば、かなりの汎用性のある技術かと思います。
今回のように手ごろに検証環境を用意したい場合だけでなく、本格的なアプリケーション開発の環境までも一瞬で構築することが可能となります。

実際のアプリケーション開発環境を構築してみたい方はこちらの記事も参考にしてみてください！！
[DockerとWSL2を使ってReact&Django&MySQLの開発環境を作る](https://qiita.com/eiji-noguchi/items/42ce3679af910c22fc21)