【初心者】DockerをインストールしてComposeでDBコンテナを作成する

#はじめに
自宅開発するにあたってDockerが便利そうなので導入しました。

##目的

* Windows環境にDocker Desktopをインストールする
* Docker-Composeでコンテナ管理を行う
 * 今回管理するコンテナはMySQLとする
 * コンテナ起動時、自動的にDBとその中のデータを生成する
 * 作成したコンテナのDBは外部のAPIから呼び出しする

##環境
| ツール            | バージョン   |
|:-----------------|:------------|
| OS               | Windows 10  ​|
| Docker Desktop   | 4.4.4       ​|
| Docker-Compose   | 2.2.3       |

#Docker Desktopの導入
まずはDocker Desktopを導入します。
今回のバージョンは`4.4.4`です。

##1.Docker Desktopの取得
[こちら](https://www.docker.com/products/docker-desktop "Docker Desktop for Mac and Windows | Docker")からDocker Desktopを取得してインストールしてください。
![Docker](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2522187/5696ae08-e1b9-ad40-15fa-91ae9287bd6d.png)


##2.WSL2のインストール
Windows環境でDocker Desktopの起動を行うためにはWSL2が必要です。
もしDocker Desktop初回起動時にエラーメッセージが出た場合は下記の手順でWSL2のインストールを行ってください。

コマンドプロンプトを管理者権限で開き、順番に以下のコマンドを叩きます。

```bash
wsl --install -d Ubuntu
wsl --update
wsl --set-version Ubuntu 2
```

今回はUbuntuを明示的に選択していますが、他のディストリビューションでも問題ありません。
※インストール可能なディストリビューションは`wsl -l -o`で確認可能です。

インストール完了後、Docker Desktopを再度起動するとエラーが消えているはずです。

#Docker-Composeの導入
WSLを起動します。
タスクバーにて`Ubuntu`の名称で検索するか、コマンドプロンプトで`wsl.exe`を入力してください。
初回起動時に作成を求められるユーザですが、今後WSL上で管理者権限が必要となった場合はこのユーザでログインする必要があります。

以下のコマンドを順番に入力することで、Docker-Composeをインストールすることができます。

```bash
curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
```

`docker-compose --version`
バージョンが返ってきたら無事インストール完了しています。

#Docker-Composeの利用
今回はDocker-Composeで定義して、DBのコンテナを作成します。
手法は[こちらの記事](https://qiita.com/TAMIYAN/items/ed9ec892d91e5af962c6 "DockerでMySQLを使ってみる - Qiita")を参考にさせていただきました。

##1.コンテナ定義作成
ディレクトリ構成は以下のように作成しました。

```:
DockerCompose
└mysql_world
    │  Docker-Compose.yml
    │
    └─world
        │  Dockerfile
        │  my.cnf
        │
        └─DB
                world.sql
```

補足として、コンテナビルド用ディレクトリはどこにおいても問題ありません。
`world.sql`は[MySQL公式](https://dev.mysql.com/doc/index-other.html "MySQL :: Other MySQL Documentation")のExample Databasesにあるworld databaseをDLして解凍したファイルを利用しています。

その他ファイルの定義は以下で説明します。

###Docker-Compose.yml
基本的な定義内容については[こちらの記事](https://qiita.com/zembutsu/items/9e9d80e05e36e882caaa "Docker Compose - docker-compose.yml リファレンス - Qiita")がわかりやすく参考になりましたので其方をご覧ください。

```Docker-Compose.yml
version: "3.8"
services:
  mysql:
    build: ./world/
    volumes:
      - ./world/db:/docker-entrypoint-initdb.d
    image: mysql_world
    environment:
      - MYSQL_ROOT_PASSWORD=【DBのパスワード】
      - MYSQL_TCP_PORT:3306
      - MYSQL_DATABASE:world
```

ポイントは、ボリュームに`docker-entrypoint-initdb.d`を設定することです。
この内部に配置したSQLがコンテナ起動時に自動実行されます。

以下リンク先のInitializing a fresh instanceに詳細の記載がありますので気になる方はどうぞ。
[Mysql - Official Image | Docker Hub](https://hub.docker.com/_/mysql "Mysql - Official Image | Docker Hub")

`environment`に定義した`MYSQL_DATABASE`はアプリケーションから接続する場合のDB名称となります。

###Dockerfile

```Dockerfile:Dockerfile
#使うDockerイメージ
FROM mysql:8
#ポートを開ける
EXPOSE 3306
#MySQL設定ファイルをイメージ内にコピー
ADD ./my.cnf /etc/mysql/conf.d/my.cnf
#docker runに実行される
CMD ["mysqld"]
```

Dockerfileの内容は参考記事とほぼ変わりありません。`mysql`イメージのバージョンについて、明示的に`8`を利用するよう定義を追加しました。
もし他のコンテナと被る場合はポート番号を変更します。

###my.cnf

```my.cnf
[mysqld]
character-set-server=utf8
[mysql]
default-character-set=utf8
[client]
default-character-set=utf8
```

此方も参考記事から変更ありません。文字コードの設定を行います。
以上でコンテナ定義については作成完了です。

##2.コンテナのビルド
コンテナをビルド・実行します。
ビルドしたい定義のあるディレクトリで以下のコマンドを叩いてください。

```bash
Docker-Compose build
Docker-Compose up -d
```

`docker ps -a`でコンテナが作成されているかどうか確認することができます。

```bash:実行結果
> docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED        STATUS        PORTS                                         NAMES
327dc1e0168e   mysql_world    "docker-entrypoint.s…"   2 hours ago    Up 2 hours    3306/tcp, 33060/tcp                           mysql_world-mysql-1
```

起動したいコンテナのNAMESを【コンテナ名】に入れてコマンドを叩きます。

```bash
docker exec -it 【コンテナ名】 bash -p
```
```mysql
mysql -u root -p -h 127.0.0.1
```

ここでパスワードの入力が求められるので、`Docker-Compose.yml`で定義したパスワードを入力して認証します。
以下のログが流れて起動完了になります。

```bash:実行結果
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 8.0.28 MySQL Community Server - GPL

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
```

そのままSQLを実行しますと、初期設定用SQLで記載したworldテーブルが作成されています。

```sql:実行結果
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| world              |
+--------------------+
5 rows in set (0.00 sec)
```

コンテナ作成までは以上です。

作ったコンテナは以下コマンドで削除することができます。
`docker-compose down --rmi all --volumes --remove-orphans`

#外部から接続する
Javaで接続する場合のデータソース設定は以下のような記載になります。

```application.yml
## データソース設定
spring:
  datasource:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/world
      username: root
      password: hoge
```

`127.0.0.1`：IPアドレス。localhostと同義。
`3306`：DockerfileとDocker-Composeに設定したポート番号。
ポイントはこの2点。
複数のDBコンテナを作成する場合はポート番号が被らないように気を付けましょう。

#おしまい
以上