Dockerでのデータベース環境構築in Spring boot(IntellJ)


#Spring boot + dockerでデータベース連携するぞ！
初記事。
ご指摘たくさんください。

Spring bootでポートフォリオを作ろうと思った時にdockerでのDB構築に手間取ったのでメモ。

###今回のゴール
サンプルプロジェクトにてdockerを用いて構築したデータベース(Mysql)の値を画面へ出力する

###・対象読者...
docker初心者
   or
開発経験の浅い（１、２年）エンジニア

###今回注力する観点
・dockerfileの作成の仕方
・docker上に作成したMySQL環境とspring bootプロジェクトの連携


※dockerの概念などはザックリ説明→とりあえずdockerとアプリケーションを連携するところまで


##dockerとは

[@kotaro-dr](https://qiita.com/kotaro-dr)さんの記事を載せさせていただきます。
[【図解】Dockerの全体像を理解する -前編-](https://qiita.com/kotaro-dr/items/b1024c7d200a75b992fc)
┗ドキュメントが綺麗で初学者でもかなりわかりやすい
[【図解】Dockerの全体像を理解する -中編-](https://qiita.com/kotaro-dr/items/88ec3a0e2d80d7cdf87a)
┗中編の最初にはデータベースの永続化にも関わってくるデータ管理の話が出てくるので今回は最低そこまでチラ見すればOKです。
ついでに後編も載せておきます。
[【図解】Dockerの全体像を理解する -後編-](https://qiita.com/kotaro-dr/items/40106f13d47bfcbc2572)


##なぜdockerなのか
・Vurtualboxよりも軽量である←テーマと焦点がズレるため詳しくは割愛。
・開発環境をすぐに用意できる
┗「この端末では動くのに自分の端末では動かない。」ということがなくなる。
┗知り合いに質問したりteratailなどのQAサービスで質問したりするときに自分の今の環境をそのまま相手に渡すことができ、回答が返って来やすくなる。
※今回はローカルマシンにIntelliJとJavaが入っていることを前提に進めます。Javaをdockerに含めることもできますが今回の観点を
「dockerでのMysql環境の構築とアプリケーションとの連携」としているため。
IntelliJとJavaのインストールについては以下に載せます。
■IntelliJ
[IntelliJ -for mac](https://qiita.com/TKR/items/df20b3df52c849f92372)
[IntelliJ -for Windows](https://pleiades.io/help/idea/install-and-set-up-product.html)
■Java11
[Java -for mac](https://weblabo.oscasierra.net/java-install-oracle-jdk11-macosx/)
[Java -for Windows](https://qiita.com/shibafu/items/8762636f66d7fef49d59)



##早速やってみよう
■環境情報
言語:Java(jdk11)
FW:Spring boot
IDE:IntelliJ
※今回、IDEをIntelliJにしてみました。操作感はほぼeclipseと同じですが、UIがなんかいい感じ。今では世界シェアはeclipseを抜いているとかいないとか。。。
まずはプロジェクトを簡単に作ってみたいと思います。
その前にIntelliJにjdkのパスを登録します。以下リンク内で、【Javaプロジェクトの作り方】を検索すると出てきます。
[JDKの登録](https://qiita.com/syu_chan_1005/items/46f94412f7493d6e60eb)

今回作成するプロジェクトのtreeです。(画像ですみません）

<img width="1680" alt="スクリーンショット 2019-02-24 15.49.49.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/303093/969cdcf1-a8a6-5252-30a6-6d09983a19fb.jpeg">


今までリンクばかりでしたが、そろそろ自分の言葉を出していきたいと思います。
###プロジェクトの作成
今回はデータベースの値を全て出す簡単なモノを作ります。
というか見ればわかるレベルなので3分クッキングパターンで、出来たものが以下になります。
[spring-boot-docker(github)](https://github.com/yosuke0517/spring-boot-docker)
※要所でコメントを入れていますのでもし解釈が間違っている等ありましたらご指摘頂けると助かります。
####`application.properties`について
```properties
spring.datasource.url=jdbc:mysql://localhost:3306/demo?characterEncoding=UTF-8&serverTimezone=JST 
#//demoが今回のデータベース名
spring.datasource.username=root //ユーザ名
spring.datasource.password=p@ssw0rd  //パスワード
spring.jpa.hibernate.ddl-auto=update  //アプリケーション起動時に、Entityに対応するテーブルがなければ作成
```

こちらはデータベース連携に必要な最低限の設定です。のちに作成するdocker-compose.ymlの内容と合わせる必要がありますので注意してください。

###dockerfileの作成
今回はsrcと同じ階層にdockerというフォルダを作成しその中に関連ファイルを作っていこうと思います。
場所についての記述が見つけられなかったため特に指定はないと認識しています。

```dockerfile:fockerfile

FROM mysql:8.0  #dockerhubより取得するイメージを指定

RUN /bin/cp -f /etc/localtime /etc/localtime.org
RUN /bin/cp -f /usr/share/zoneinfo/Asia/Tokyo /etc/localtime

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

RUN mkdir -p /var/log/mysql
RUN chown mysql.mysql /var/log/mysql

```
COPY：コマンドの左側がローカル側、右側がdockerイメージ側のことを書いております。
RUN：対象のイメージにインストールされているコマンドを実行できる


```ruby:docker-compose.yml
version: '3'
services:
    mysql:
        build: ./mysql
        environment:
            - MYSQL_DATABASE=demo
            - MYSQL_ROOT_USER=root
            - MYSQL_ROOT_PASSWORD=p@ssw0rd
            - TZ=Japan
        volumes:
            - ./initdb.d:/docker-entrypoint-initdb.d
            - ./dbdata:/var/lib/mysql
        ports:
            - "3306:3306"
```

#↑コロン(:)で区切られている場合
#####・左側がホスト側、右側がコンテナ側のパスを表す
#####・初期データ投入→initdb.dディレクトリに最初に読み込むsqlファイルを入れる
#####永続化→dbdataに処理をするごとにデータ相当のファイルがどんどん入ってくる

#docker-composeを起動させよう
プロジェクト上のdocker-compose.ymlを右クリックし「再生」をします。
<img width="1680" alt="スクリーンショット 2019-03-01 22.49.47.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/303093/450f6ed5-5e65-870a-9042-552391124ef2.jpeg">
すると、さっき書いた`dockerfile`や`docker-compose.yml`を解釈してせっせか環境構築が始まります。
以下のように`'Compose: docker' has been deployed successfully.`と出たら完成です。
<img width="1680" alt="スクリーンショット 2019-03-01 22.53.15.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/303093/cda6fdad-6653-4125-ce3c-d128f4683677.jpeg">

では早速、データベースが出来上がっているかコンテナに入って確認してみます。
ターミナル（Windowsの場合はコマンドプロンプト）でプロジェクトのディレクトリへ移動します。
その中で
`docker ps`コマンドで現在のコンテナの稼働状況を確認します。
実行後が下図です
<img width="1680" alt="スクリーンショット 2019-03-02 0.18.36.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/303093/6181876c-637e-e259-3c02-37865fe5e1f2.jpeg">

mysqlのイメージができていることがわかります。
起動にはこちらのCONTAINER IDもしくはNAMESを使います。今回はCONTAINER IDを使って起動してみます。

`docker exec -it 【CONTAINER ID】 bash`でコンテナに入ります。
`root@37c06170b19b:/# `こんな感じのターミナル（コマンドプロンプト）になっていれば入れています。
この画面よりrootユーザでMysqlへ接続します。
`mysql -u root`
今回はパスワードを`p@ssw0rd`としてます。
以下のようにmysqlへ接続
<img width="1680" alt="スクリーンショット 2019-03-02 0.40.51.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/303093/5eec59a2-cfdf-0cd3-3b4c-6f92afdad97a.jpeg">

`use demo`で今回のサンプルデータベースを指定。あとは適当にsqlをうって確認します。初期データとしては`user`テーブルが入っていますので。
`select * from user;`
<img width="1680" alt="スクリーンショット 2019-03-02 0.46.40.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/303093/22219438-e6dd-165f-8ab2-47ba0a59ba8f.jpeg">
テーブルの中身を確認できました。

あとは自分のショボいサンプルプロジェクトを`DockerApplication`から実行すると...
以下のようにデータベースとの連携に成功しました。
![スクリーンショット 2019-03-02 0.52.29（2）.jpg](https://qiita-image-store.s3.amazonaws.com/0/303093/1a33c871-4fa0-f6dd-e72f-837165f024af.jpeg)


このようにdockerを使えば環境ごと相手に渡すことができるのでわざわざ相手にデータベースのセットアップやデータの投入をさせずに済みます。
dockerの知識はまだまだ浅いですが、これからどんどん使われていく事になると思いますので、積極的に使っていきたいものです。

次回は、Spring bootで認証画面を試してみたいと思います。