はじめに
個人開発したプロジェクトのリポジトリをGitHubにpushするにあたり、DBの環境構築を簡単に再現にできるよう、Dockerコンテナを活用することにしました。
Dockerコンテナ内にMySQLのDBを作成し、MyBatisと連携させたJavaアプリケーションから接続しようとした際につまずいたポイントなどを備忘録的に残しておきたいと思います。
本編(①コンテナ作成編)では、Docker Desktopのインストール〜コンテナを作成するまでを、「②コンテナ接続編」ではMyBatisと連携させたJavaアプリケーションからコンテナ内のDBへ接続する手順を、「③番外編」ではコンテナ作成時の警告メッセージについて記載しています。
コンテナを作成
1. Rosetta2をインストール
Rosetta2を使用すると、Appleシリコンを搭載したMacでもIntelプロセッサを搭載したMac用に開発されたAppを使用できるように変換してくれます。
Docker Desktop4.3.0ではハードウェア要件からは削除されており、今回のケースでは特に必要はありませんが、インストールが推奨されているため、今後を見据えて念のためにインストールしておきます。
$ softwareupdate --install-rosetta
2. Docker Desktopをインストール
3. docker-compose.ymlを作成
プロジェクトのルートディレクトリにdockerディレクトリを作成し、その中にdocker-compose.ymlを作成します。
- MySQLのバージョンはホストOS上のMySQLと合わせた
- 今回のケースでは、DB名は統一したかったため、PWのみ環境変数で設定
- 個人開発のためUSER等はせず
- DB内で日付を扱うため、TZも設定
services:
db:
image: mysql:8.0.42
container_name: break_spell_db
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: break_spell
TZ: Asia/Tokyo
ports:
- "3306:3306"
volumes:
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
- db_data:/var/lib/mysql
command: --default-authentication-plugin=mysql_native_password
volumes:
db_data:
上記の設定コードのうち、command:
に記載した内容は、MySQL8.0以降は非推奨のため、警告メッセージが出力されます。
警告メッセージの詳細は③番外編にて紹介しています。
4. .envファイルを作成
docker-compose.ymlと同様にdockerディレクトリに作成します。
- 今回はPWのみ環境変数にしたため、PWのみ設定
MYSQL_ROOT_PASSWORD=Your_PW
5. init.sqlを作成
docker-compose.yml, .envファイルと同様にdockerディレクトリに作成します。
-- 注意:
-- Windowsで実行する場合は文字化け防止のために、構文の末尾に 'DEFAULT CHARSET=utf8' を指定してください。
-- 例)CREATE TABLE player_score (...) DEFAULT CHARSET=utf8;
CREATE DATABASE IF NOT EXISTS break_spell;
USE break_spell;
CREATE TABLE player_score(
id INT AUTO_INCREMENT,
player_uuid VARCHAR(36),
player_name VARCHAR(16),
score INT,
difficulty VARCHAR(6),
registered_at DATETIME,
PRIMARY KEY (id));
CREATE TABLE player_progress(
player_uuid VARCHAR(36),
difficulty VARCHAR(6),
played BOOLEAN,
cleared BOOLEAN,
cleared_at DATETIME,
PRIMARY KEY (player_uuid, difficulty));
今回使用したデータでは絵文字等を含み得ない内容だったため、文字エンコーディングの指定に'utf8'を使用するようコメントしておりますが、通常はより拡張性や互換性の高い'utf8mb4'の使用が推奨されています。
6. コンテナを作成
dockerディレクトリに移動し、コマンドを実行します。
-
-d
オプションを付与し、バックグラウンドで実行
$ cd {docker}
## 続けてコマンド操作ができるように「-d」オプションを付与
$ docker compose up -d
7. コンテナが作成されているかを確認
## 実行中のコンテナを一覧表示
$ docker container ls
下図のように、NAMESにdocker-compose.ymlで指定したコンテナ名があり、STATUSが「Up」になっていれば成功です。
作成されたコンテナは、Docker Desktopからも確認することができます。
8. コンテナ内にDBが作成されているかを確認
コマンドを実行し、コンテナ内にDBが作成されているかを確認します。
$ mysql -u root -p
## PW入力後、DBが作成されているか確認
$ SHOW DATABASES;
作成されて……ない!
原因
ホストOS上のMySQLにログインしてしまっていたことが原因でした。
コンテナはホストOSから隔離された環境のため、ホストOS上のMySQLにログインしてもコンテナ内に作成したDBを確認することはできません。
## これだとホストOS上のMySQLにログインしている
$ mysql -u root -p
解決策
docker exec
コマンドを使ってコンテナ内にシェルを起動することで、コンテナ内のMySQLにログインすることができ、無事にDBおよびテーブルが作成されたことを確認できました。
-
docker exec -it {docker-compose.ymlで指定したコンテナ名} mysql -u root -p
で作成したコンテナ内のMySQLにログイン - コンテナ名はdocker-compose.ymlまたは
docker container ls
で確認可能
## コンテナ名なんだっけ?となった場合に確認
$ docker container ls
## コンテナ内を確認する必要があるので、こちらが正解
## docker exec -it {コンテナ名} mysql -u root -pでコンテナ内のMySQLにログイン
$ docker exec -it break_spell_db mysql -u root -p
## PW入力後、DBとテーブルが作成されているか確認
$ SHOW DATABASES;
$ USE break_spell;
$ SHOW TABLES;
docker exec
は、実行中のコンテナで新たにコマンドを実行するコマンドです。
-it
オプションの意味はそれぞれ以下のとおり。
-i
: 標準入力を受け付ける(=キーボード入力できる状態にしておく)。
-t
: 擬似ターミナルを割り当てる。
つまり、docker exec -it
コマンドは、「コンテナ内に新しく擬似ターミナルを用意して、キーボードからのコマンド入力を可能にする」 コマンドということですね。
[参考] https://docs.docker.com/reference/cli/docker/container/exec/
おわりに
これで、dockerコンテナおよびDBの準備が完了しました。
最後までお読みいただきありがとうございました。
次回、「②コンテナ接続編」では、いよいよMyBatisと連携させたアプリケーションから、本編で作成したコンテナ内のDBへの接続を試みます!