SpringBoot 向けのMySQLセットアップ

SpringBoot向けのMySQLサーバーのセットアップの手順を整理
## 目的
SpringBoot向けのMySQLサーバーをDockerを使ってセットアップ覚え書き
永続化設定済みでMySQLコンテナ起動確認まで

MacOsの場合もほとんど同じようにできるがRancherDesktopで追加の設定が必要。
こちらの記事をご覧ください。

https://qiita.com/dorayakin/items/b26262aa50caac039265

## 環境

WSL バージョン: 2.3.26.0
カーネル バージョン: 5.15.167.4-1
WSLg バージョン: 1.0.65
MSRDC バージョン: 1.2.5620
Direct3D バージョン: 1.611.1-81528511
DXCore バージョン: 10.0.26100.1-240331-1435.ge-release
Windows バージョン: 10.0.22631.4460
Rancher Desktop V1.16.0
MySQL 8.0

## プロジェクト作成
まずは[SpringInitializr](https://start.spring.io/#!type=maven-project&language=java&platformVersion=3.3.5&packaging=jar&jvmVersion=21&groupId=com.example&artifactId=demo&name=demo&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.demo&dependencies=)を使用してプロジェクトのひな形を生成。
今回はDBの起動までなので依存ライブラリの設定などはシンプルに無しで進める。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310625/22f70eaf-51a8-df19-bc6c-8f9637badd66.png)

demoプロジェクト内は以下の構成になっている。
```
.
├── .mvn
│   └── wrapper
│       └── maven-wrapper.properties
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com
│   │   │       └── example
│   │   │           └── demo
│   │   │               └── DemoApplication.java
│   │   └── resources
│   │       └── application.properties
│   └── test
│       └── java
│           └── com
│               └── example
│                   └── demo
│                       └── DemoApplicationTests.java
├── .gitattributes
├── .gitignore
├── HELP.md
├── mvnw
├── mvnw.cmd
└── pom.xml

```
srcと同じ階層にinfraフォルダを作成し、さらにdbフォルダを追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310625/aa39bbf9-0942-eef7-fa8a-8ae8952b97a9.png)
## MySQLコンテナ作成
コンテナの設定とMySQLの設定のために次の2つのファイルを作成する。
- Dockerfile
- my.cnf

:::note info
my.cnfファイルはMySQLの設定ファイル。
格納先は複数あり、読み込み優先度が異なる。
:::

### Dockerfile作成
`demo\infra\db\Dockerfile`に`Dockerfile`を作成する。

```Dockerfile
FROM mysql:8.0

COPY ./conf.d/my.cnf /etc/mysql/conf.d/my.cnf

RUN chmod 644 etc/mysql/conf.d/my.cnf

RUN mkdir -p /var/log/mysql \
    && chown -hR mysql:mysql /var/log/mysql
```
 **Dockerfileの内容**
1. MySQLのバージョンを指定
2. MySQLの設定ファイルをコンテナ内に複製
3. 設定ファイルの権限変更 
4. サブディレクトリを含めて/var/log/mysqlを作成
5. ディレクトリとシンボリックリンクの両方の所有者をmysqlに変更 
### MySQL設定ファイルmy.cnf作成
`db`フォルダに`conf.d`フォルダを作成する。
`conf.d`フォルダに`my.cnf`ファイルを作成する。
`my.cnf`のパスは`demo\infra\db\conf.d\my.cnf`となる。



my.cnfの中身は次のように設定する。
[mysqld]はMySQLサーバーが対象の設定を表す。

:::note info
他に[client]などがあり、[client]の場合はコンテナで使用するMySQLクライアントの設定を表す。
:::
```my.cnf
[mysqld]
#error log
log-error = /var/log/mysql/mysql-error.log

#slow query log
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 1.0

#general log
general_log = 1
general_log_file = /var/log/mysql/mysql-general.log
```
今回はログの出力先等を設定している。


## composeコマンド準備
docker composeのコマンドを使用するための準備。
infraフォルダに次の2つのファイルを作成する。

- compose.yml 
- .env
### compose.yml
```yml
services:
  db:
    build: ./db
    restart: always
    container_name: mysql-container
    ports:
      - "${FORWARD_DB_PORT:-3306}:3306"
    environment:
      MYSQL_ROOT_PASSWORD: "${DB_PASSWORD}"
      MYSQL_ROOT_HOST: "%"
      MYSQL_DATABASE: "${DB_DATABASE}"
      MYSQL_USER: "${DB_USER}"
      MYSQL_PASSWORD: "${DB_PASSWORD}"
    volumes:
      - db_store:/var/lib/mysql
      - ./db/logs:/var/log/mysql
volumes:
  db_store:
```
`build:`の部分で指定したディレクトリをのDockerfileを使用してコンテナを作成できる。
`restart: always`でコンテナが停止したときに自動で再起動するように設定。
`ports:`の`"${FORWARD_DB_PORT:-3306}:3306"`は環境変数`FORWARD_DB_PORT`が設定されていない場合デフォルトで3306ポートを使用することを表す。

トップレベルの`volumes:`は複数のコンテナを横断してボリュームを利用する場合必要となる。
### .envファイル
```.env
FORWARD_DB_PORT= 3306

DB_DATABASE= demoMySQL
DB_USER= demouser
DB_PASSWORD= demopassword
```

さらにdemoプロジェクト内の`.gitignore`ファイルに .envファイルとdbのログフォルダを追加する。

```.gitignore
#env
.env
#db logs
demo/infra/db/logs/
```


## イメージ作成
RancherDesktopが起動していることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310625/7571c451-8a78-b097-bb61-ff868e35dde6.png)
次のコマンドを
`demo\infra`の階層で実行する。
```console
docker compose build
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310625/bf3bca90-9419-be41-b5f0-f407f1954c68.png)

エラーにならず完了すればOK。

:::note info
`demo\infra\db`で`docker images`のコマンドを打つとビルドされたイメージを確認することができる。
:::

## コンテナ起動
作成したイメージをもとにコンテナを作成して起動する。
`demo\infra`の階層で次のコマンドを実行することで起動まで行える。

```console
docker compose up
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310625/01a1f40b-2b66-92b6-23ec-8033e4c5d12f.png)
(timezoneを設定していないためtimezone周りの設定をskipするメッセージが出る。)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310625/97d11be0-dcc2-946e-fce8-6a2f9062d808.png)
既にコンテナは起動済み。
次の画像のようにlogsのフォルダが自動で生成されログが格納される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310625/fc4a5432-c1cc-f8ab-808f-24ebd8c8bfdd.png)

`Ctrl+C`で次のようなメッセージを表示してコンテナを停止できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310625/8ddb9bc7-1185-5999-094e-00b0ef47ae3e.png)

:::note info
同じコンソールで作業を続けたい場合は`docker compose up -d`でバックグラウンド起動を行う。
下記のdocker compose upのリンクに詳しく記載されている。
:::

https://docs.docker.com/reference/cli/docker/compose/up/

コンテナを起動した状態で`demo\infra`で`docker compose ps -a`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310625/56265979-4238-9ee4-0338-da1de73f3a67.png)

:::note info
`docker compose ps`に`-a`オプションをつけると停止中のコンテナも一覧に表示することができる。(つけていない場合は起動中のコンテナのみ表示される。)
:::
STATUSが`Up 27 seconds`となっていて無事コンテナが起動していることが確認できた。

## 続き

https://qiita.com/dorayakin/items/9fde425566ed41b08e12

## 補足
- イメージとコンテナを削除する
```
docker compose down
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310625/479156c7-6dc6-4ae8-2536-7e91b6f46100.png)
- イメージ、コンテナ、ボリュームをまとめて削除する
```
docker compose down -v
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310625/0bd32404-6aa8-87e7-e31a-3da39142e19e.png)

## 参考
https://docs.docker.jp/engine/reference/builder.html

https://docs.docker.jp/compose/toc.html

https://github.com/dorayakin/MySQL-Demo-Spring