初学者向け：Dockerを使って簡単にMySQL環境を構築し、SELECT文で動作確認する方法

## はじめに

Dockerを利用することで、アプリケーション環境の構築と管理が簡単に行えます。

:::note warn
**本記事では、Dockerfile を使用して MySQL コンテナをカスタマイズし、初期データを投入する方法を解説します。**
:::

未来の自分への備忘録としても活用できるよう、基礎的な部分を体系的にまとめています。そのため、***Docker初心者の方にも役立つ内容となっています！***

## 前提条件
以下の環境が整っていることを前提に、実際にハンズオンを進めていきます。

:::note info
- **Dockerがインストールされ、起動していること**
- **基本的なコマンドライン操作の知識**
- **任意のテキストエディタ（例: VS Code, Vim, etc.）**
:::

また、Dockerの基礎知識については、以下の記事で解説していますので、参考にしてください。

https://qiita.com/free-honda/items/6273289e813eabcbd9d9

## ディレクトリ構成

本記事で作成するプロジェクトのディレクトリ構成は以下の通りです。

```ディレクトリ構成.
mysql-docker/
├── init.sql            # 初期化用のSQLスクリプトファイル
└── Dockerfile          # Dockerの設定ファイル
```

:::note warn
**シンプルでわかりやすいディレクトリ構成にしています。**
:::

## 実際にやってみた

### プロジェクトの準備

ターミナルで以下のコマンドを実行し、プロジェクト用のディレクトリを作成します。

```bash
mkdir mysql-docker
cd mysql-docker
```

## 必要なファイルを作成

次に、以下の2つのファイルをプロジェクトディレクトリに作成します。

:::note info
- ***```init.sql```***: 初期化用のSQLスクリプトファイル
- ***```Dockerfile```***: Dockerの設定ファイル
:::

### Dockerfile の作成

以下の内容で ```Dockerfile``` を作成します。

```Dockerfile
# ベースイメージとして MySQL を使用
FROM mysql:latest

# MySQL の初期設定を環境変数で指定
ENV MYSQL_ROOT_PASSWORD=my-secret-pw
ENV MYSQL_DATABASE=my_database
ENV MYSQL_USER=my_user
ENV MYSQL_PASSWORD=my_password

# カスタムの初期化スクリプトをコピー（必要に応じて）
COPY ./init.sql /docker-entrypoint-initdb.d/

# デフォルトのポートを公開
EXPOSE 3306
```

### 初期化用 SQL ファイルの作成

初期化用の SQL スクリプトを作成します。このファイルは、コンテナ起動時に自動的に実行されます。

以下は ```init.sql``` の例です。

```init.sql
CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(100) NOT NULL
);

INSERT INTO users (name, email) VALUES ('honda', 'honda@example.com');
```

## Dockerイメージのビルド

```Dockerfile``` を基に ```Docker``` イメージをビルドします。

```bash
docker build -t custom-mysql .
```

```-t custom-mysql```: イメージ名を ```custom-mysql``` に指定します。```.```: 現在のディレクトリを指定しています。

![スクリーンショット 2024-12-11 16.08.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/c12ef00d-e6be-4557-6008-615bd06aa55c.png)

上記のコマンドを実行すると、```Dockerfile``` の内容に基づいてコンテナイメージが作成されます。

## コンテナ実行

ビルドしたイメージを使って、コンテナを作成・起動します。

```bash
docker run --name custom-mysql-container \
  -p 3306:3306 \
  -d custom-mysql
```

```--name custom-mysql-container```: コンテナ名を ```custom-mysql-container``` に指定します。

![スクリーンショット 2024-12-11 16.09.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/a4e50487-22ce-7382-a404-4eb4b44bed4d.png)

:::note warn
***```-p 3306:3306:``` ポートのマッピングを行います。***
:::

## アプリケーションの確認

コンテナ内の MySQL に接続し、初期化したデータやテーブルが正しく反映されているか確認します。

```bash
docker exec -it custom-mysql-container mysql -u root -p
```

パスワードとして ```my-secret-pw``` を入力し、SQL クエリを実行します。

```bash
USE my_database;
SELECT * FROM users;
```

クエリの結果が以下のように表示されれば、成功です。

![スクリーンショット 2024-12-11 16.46.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/e3791170-5604-f0f9-25d7-31972e515363.png)

出力結果から、データが挿入され、```SELECT``` 文で正しく取得できていることが確認できました。

```.sql
+----+-------+-------------------+
| id | name  | email             |
+----+-------+-------------------+
|  1 | honda | honda@example.com |
+----+-------+-------------------+
```

## まとめ

この記事では、```Dockerfile``` を使用して簡単にMySQL環境を構築する方法をご紹介しました。

:::note warn
***今回はDockerの基礎的な内容を扱いましたが、基本をしっかり理解することでDockerやコンテナに関する知識がさらに深まります。***
:::

今後もDocker関連の知識を整理しながら発信していきますので、この記事が誰かの技術的な参考になれば嬉しいです。

## おまけ：シェルスクリプトで一括作成してみた
手動でディレクトリとファイルを作成するのが少し面倒に感じたので、ディレクトリ構造と必要なファイルを一括で作成するシェルスクリプトを作成しました。

```test.sh
#!/bin/bash

# プロジェクトのベースディレクトリ名
PROJECT_DIR="mysql-docker"

# 初期化用のSQLスクリプトの内容
INIT_SQL_CONTENT="""CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(100) NOT NULL
);

INSERT INTO users (name, email) VALUES ('honda', 'honda@example.com');
"""

# Dockerfileの内容
DOCKERFILE_CONTENT="""# ベースイメージとして MySQL を使用
FROM mysql:latest

# MySQL の初期設定を環境変数で指定
ENV MYSQL_ROOT_PASSWORD=my-secret-pw
ENV MYSQL_DATABASE=my_database
ENV MYSQL_USER=my_user
ENV MYSQL_PASSWORD=my_password

# カスタムの初期化スクリプトをコピー（必要に応じて）
COPY ./init.sql /docker-entrypoint-initdb.d/

# デフォルトのポートを公開
EXPOSE 3306
"""

# ディレクトリの作成
if [ -d "$PROJECT_DIR" ]; then
  echo "$PROJECT_DIR ディレクトリは既に存在します。" >&2
  exit 1
fi

mkdir "$PROJECT_DIR"
echo "$PROJECT_DIR ディレクトリを作成しました。"

# init.sql の作成
echo "$INIT_SQL_CONTENT" > "$PROJECT_DIR/init.sql"
echo "init.sql を作成しました。"

# Dockerfile の作成
echo "$DOCKERFILE_CONTENT" > "$PROJECT_DIR/Dockerfile"
echo "Dockerfile を作成しました。"

# 処理完了
echo "プロジェクト構成が完了しました。"
echo "ディレクトリ構成:"
tree "$PROJECT_DIR"
```

***このスクリプトを実行すれば、ディレクトリ構造と初期ファイルなどが自動で作成されます。***

## 関連記事

https://www.kagoya.jp/howto/cloud/container/dockermysql/

https://zenn.dev/ryo7/articles/create-mysql-on-docker

https://qiita.com/taniann/items/ed9ec892d91e5af962c6

https://zenn.dev/bloomer/articles/7c879ab2a67abc

https://qiita.com/free-honda/items/068adffee2bea5bcca24