DockerComposeを使わない、DockerfileでMySQLに初期データを投入しよう！

<注意>
この記事は、<b>「取り急ぎDockerでMySQL環境を使ってみたい」</b>という初学者向けの内容となっております。
<br>

ネット上にDockerComposeを使ってやる方法はたくさん転がっていますが、DockerComposeを使わず、Dockerfileでこれを行う方法があまりなかったので今回記事にしました！（まあMySQLを含むデータベースは他のサービスと連動してナンボなので、そもそも単体で使うことは学習段階以外ではほぼないと思いますが。）
「だったら最初からCompose使えば良くない？」
と思われるかも知れませんが、私のように
「Composeいまいち理解してないんだよなぁ。理解しないまま使いたくないし、だけど取り急ぎDockerでMySQLの学習を行いたい。」
という人が世の中に一人でもいると信じて！この記事を書きます。
「いやいや、データベースは他のサービスと連動させるのが当たり前なんだから黙ってComposeを使おうぜ！」
という方、その意見ごもっともです。。。
ただ最初に申した通り、この記事は、<b>「取り急ぎDockerでMySQL環境を使ってみたい」</b>という初学者向けなのでご容赦ください。。。
今回は初学者向けに、これを真似すればとりあえずテーブルの作成できて、データの投入ができることを目指しましたので、少し長くなると思いますがお付き合いください。

# 1. 何はともあれDockerfileを作る
早速ですが、Dockerfileを作ります！
```dockerfile
FROM mysql:8.0.33
RUN microdnf install yum && \
yum install -y glibc-langpack-ja glibc-locale-source git && \
localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
ENV LC_ALL=ja_JP.UTF-8
ENV LANG=ja_JP.UTF-8
COPY my.cnf /etc/mysql/conf.d
COPY create-table.sql /docker-entrypoint-initdb.d
ENV MYSQL_ROOT_PASSWORD=<任意のパスワード>
ENV MYSQL_DATABASE=<任意のデータベース名>
```
ひとつずつ解説しますね！
```docker
FROM mysql:8.0.33
```
- 最初に使用するMySQLのイメージを指定。ここではMySQLのVersion8.0.33を使います。
```docker
RUN microdnf install yum && \
yum install -y glibc-langpack-ja glibc-locale-source git && \
localedef -f UTF-8 -i ja_JP ja_JP.UTF-8
```
- microdnfを使用してyumをインストール。
- Gitと日本語化のために必要なパッケージをインストール。
- システムにUTF-8エンコーディングの日本語ロケールを定義。
```docker
ENV LC_ALL=ja_JP.UTF-8
ENV LANG=ja_JP.UTF-8
```
- すべてのロケールにおいて日本語を指定。
- デフォルトのロケールを指定。
※これが意外と重要（？）で、先程日本語化に必要なパッケージをインストールしてロケールを定義したはずなのに、実際にコンテナを起動してMySQLを操作しようと思ったら<font color="red">日本語が入力できない</font>という状況に陥る事があるので、入れておいたほうが良いです。
私の環境ではこれがないと、<font color="red">日本語入力は出来るけど、Enter押したら消える</font>という現象があり、これの解決に結構時間を取られました。
```docker
COPY my.cnf /etc/mysql/conf.d
```
- 「my.cnf」を、MySQLの設定ファイル「conf.d」にコピー。
  ※my.cnfは後で作成します。
```docker
COPY create-table.sql /docker-entrypoint-initdb.d
```
- 「create-table.sql」を「docker-entrypoint-initdb.d」コピー
  ※これが今回の主役！後ほど作成するcreate-table.sqlをコンテナ起動時に実行されるようにdocker-entrypoint-initdb.dの中にコピーします。こうすることで、コンテナ起動時に、create-table.sql内のコマンドが実行されます。
```docker
ENV MYSQL_ROOT_PASSWORD=<任意のパスワード>
```
- MySQLにrootユーザーのパスワードを設定。あとで使用します。
  ※ここでパスワードを設定するのはセキュリティ的にどうなのか！という指摘もありそうですが、今回は取っつきやすいようにこちらで設定します。
```docker
ENV MYSQL_DATABASE=<任意のデータベース名>
```
- 最後にデータベースを作成します。

# 2. 設定ファイル「my.cnf」を作る
これはMySQLの設定ファイルです。
拡張子が「.cnf」であれば名前は何でもOKです。
その時はDockerfileの「my.cnf」も変更するのを忘れないようにご注意ください！
my.confの中は以下となります。
```conf
[client]

[mysqld]
character-set-server=utf8
skip-character-set-client-handshake
default-storage-engine=INNODB

[mysqldump]
default-character-set = utf8

[mysql]
```
ここでは「このファイルで設定が必要なんだ」とだけ思っててください。
これがないとデフォルト環境でMySQLを使うこととなり不便、、、というか日本語を使う場合や、開発規模によってはほとんど使い物にならなくなると思います。

# 3. いよいよ主役が登場！create-table.sqlを作る
お待たせしました！
ようやく主役の登場です！！
ただテーブル設計の話ではないので、超絶簡単なテーブルを作ってそこにデータを入れ込むだけにします。
あ、こちらのファイル名も拡張子が「.sql」であれば任意です。

```sql
CREATE TABLE Product (
  ID INT NOT NULL PRIMARY KEY,
  Name VARCHAR(100) NOT NULL,
  Price INT NOT NULL
);

INSERT INTO Product (ID, Name, Price) VALUES (1, 'ボールペン', '150');
INSERT INTO Product (ID, Name, Price) VALUES (2, '学習ノート', '100');
INSERT INTO Product (ID, Name, Price) VALUES (3, '電卓', '550');
```
※分かりやすいようにテーブル名やカラム名、データ内容を具体的に入力しています。
Productテーブルが作成され、その中にデータが3つ入ります。

# 4. イメージをビルドして、コンテナを起動する
ではイメージをビルドしましょう！
```sh
docker build -t <任意のイメージ名>:<バージョン> 
```
続いてコンテナの作成です。
```sh
docker run -p 3306:3306 --name <任意のコンテナ名> -d -v "/product/db:/var/lib/mysql" <先程作ったイメージ名>:<そのバージョン>
```
ここではローカルのdbディレクトリをDockerのコンテナ内のmysqlディレクトリにマウントすることで、データの永続化を図っています。
さて、コンテナが作成できたら起動しましょう。
```sh
docker start <コンテナ名>
```
続いてコンテナの中に入ります。
```sh
docker exec -it <コンテナ名> /bin/bash
```
おそらくこれでコンテナの中に入れたと思います！
次はMySQLにログインしてデータを確認してみます！

# 5. MySQLにログインしてデータを確認する
まずはログインです。
```sh
mysql -u root -p
```
※これを実行するとパスワードの入力を求められますので、Dockerfileで設定したパスワードを入力します。
<br>
ログインに成功したら、存在するデータベースを確認します。
```sql
SHOW DATABASES;
```
先程Dockerfileで作成したデータベースはあるはずです。
ではそのデータベースを使用していきましょう！
```sql
USE <Dockerfileで作成したデータベース名>;
```
データベースを選択したらテーブルが出来ているか確認しましょう。
```sql
SHOW TABLES;
```
create-table.sqlで作成したテーブル（Product）があるはずです。
では中身を確認します。
```sql
SELECT * FORM Product;
```
以下のような形になっていればOKです！
|ID|Name|Price|
|----|----|----|
|1|ボールペン|150|
|2|学習ノート|150|
|3|電卓|550|

もちろん新規でデータの登録も可能です！（INSERTクエリ）
また、先程ローカルのファイルをマウントしているので、コンテナを壊しても、あとで同じイメージからコンテナを作成すればデータは保持されています！

# まとめ
いかがでしたでしょうか？
Composeを使用しなくてもMySQLの環境を構築して使うことができます！
ただ、MySQLの勉強だけならこれで問題ありませんが、実際にアプリケーションを作る場合は複数のコンテナを用意して管理する必要があるので、やはりCompose理解は必須です。
今回は取り急ぎMySQLの学習をDockerで行う方法を紹介しました。