はじめに
あんなテーブル定義を作ってみたい、こんなクエリを試してみたい…!
そんなアツい想いから、dockerを使って自分だけのDB(Mysql)環境をたててみました。
何番煎じかわかりませんが、本記事ではDockerfileやcompose.yamlの書き方から初期データの投入までを記載します。
前提
- Dockerがインストールされている
- docker-composeがインストールされている
- 基本的なSQLがわかる
ディレクトリ構成
最終的なディレクトリ構成はこのようになります。
mydb
├── Dockerfile
├── compose.yaml
└─┬ init
├── 01_create_databases.sql
├── 02_create_tables.sql
└── 03_insert_my_mdb.sql
Dockerfileの作成
わかりやすいように専用のディレクトリをきって、Dockerfileを作成します。
$ mkdir mydb
$ cd mydb
$ touch Dockerfile
$ ls -1
Dockerfile
Dockerfileは以下のように記述しました。
FROM mysql:8.0-debian
# set timezone
ENV TZ=Asia/Tokyo
# set locale
RUN apt-get update
RUN apt-get install -y locales
RUN echo "ja_JP.UTF-8 UTF-8" > /etc/locale.gen && \
locale-gen
ENV LANG=ja_JP.UTF-8
compose.yamlの作成
続いて、compose.yamlを作成します。
$ touch compose.yaml
$ ls -1
Dockerfile
compose.yaml
compose.yamlの中身を記述します。
ローカルで自分だけで遊ぶくらいなら以下のような構成で十分じゃないかと思います。
services:
db:
container_name: mydb
build: .
environment:
MYSQL_ROOT_PASSWORD: rootpass
イメージのビルド・コンテナの起動
以下のコマンドでイメージのビルドとコンテナの作成・起動を行います。
$ docker compose -p mydb up --build -d
起動ができたら、コンテナ一覧を確認してみましょう。
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2ed39f82b62c mysql:8.3.0 "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 3306/tcp, 33060/tcp mydb
コンテナが作成されていますね!
早速DBにアクセスしてみましょう。
$ docker container exec -it mydb mysql -uroot -prootpass
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.3.0 MySQL Community Server - GPL
Copyright (c) 2000, 2024, 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.
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
アクセスできました!(CLIでパスワードを設定しているのはセキュアじゃないよって怒られていますが、本記事の趣旨とは異なるため今回は無視します)
しかし、今のままだとデフォルトで作成されたデータベースがあるのみで、まだ自分が遊ぶ用のデータベースが用意されていません。
初期データを準備する
mysqlのdockerhubを確認すると、下のような記述があります。
When a container is started for the first time, a new database with the specified name will be created and initialized with the provided configuration variables. Furthermore, it will execute files with extensions
.sh
,.sql
and.sql.gz
that are found in/docker-entrypoint-initdb.d.
Files will be executed in alphabetical order.
コンテナ起動時に、/docker-entrypoint-initdb.d.
に格納された拡張子.sh
, .sql
, .sql.gz
のファイルが実行されるそうです。
つまり、ローカルに初期データ投入用の.sql
ファイルが格納されたディレクトリを用意し、/docker-entrypoint-initdb.d.
にマウントすれば、初期データの投入ができそうです。
まず、初期データ投入用の.sql
ファイルを格納するディレクトリを作成します。
$ mkdir init
$ ls -1
Dockerfile
compose.yaml
init
init
ディレクトリ内に、初期データの登録を記述した.sql
ファイルを配置します。
今回はこのようにファイルを用意しました。
$ ls -1 ./init
01_create_databases.sql
02_create_tables.sql
03_insert_my_mdb.sql
中身はこんな感じにしてみました。
$ cat ./init/01_create_databases.sql
CREATE DATABASE `my_mdb` /*DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */;
$ cat ./init/02_create_tables.sql
SET SESSION FOREIGN_KEY_CHECKS=0;
/* Drop Tables */
DROP TABLE IF EXISTS my_mdb.m_spot;
DROP TABLE IF EXISTS my_mdb.m_region;
/* Create Tables */
-- M地方
CREATE TABLE my_mdb.m_region
(
-- 地方ID
region_id bigint NOT NULL COMMENT '地方ID',
-- 地方の名称
region_name text NOT NULL COMMENT '地方名',
-- 登録された日時
created_at datetime NOT NULL COMMENT '登録日時',
-- 更新された日時
updated_at datetime NOT NULL COMMENT '更新一時',
PRIMARY KEY (region_id)
) COMMENT = 'M地方';
$ cat ./init/03_insert_my_mdb.sql
INSERT INTO my_mdb.m_region (region_id, region_name, created_at, updated_at) VALUES
(1, 'カントー地方', NOW(), NOW()),
(2, 'ジョウト地方', NOW(), NOW()),
(3, 'ホウエン地方', NOW(), NOW()),
(4, 'シンオウ地方', NOW(), NOW());
好きなゲームをもとに作ってみました、へへ。
先ほど作成したcompose.yamlに、/docker-entrypoint-initdb.d.
とinit
ディレクトリをマウントする旨を記述をします。
services:
db:
container_name: mydb
build: .
environment:
MYSQL_ROOT_PASSWORD: rootpass
volumes:
- ./init:/docker-entrypoint-initdb.d
docker-entrypoint-initdb.d
内の.sql
ファイル等は、コンテナの初回起動時のみ実行されるため、一旦いま起動しているコンテナを破棄します。
$ docker compose -p mydb down
[+] Running 2/1
⠿ Container mydb Removed 1.0s
⠿ Network mydb_default Removed 0.1s
再度docker compose up --build -d
を叩きます。
このときのログを確認してみましょう。
$ docker logs mydb
(中略)
2024-04-06 13:20:49+00:00 [Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/01_create_databases.sql
2024-04-06 13:20:49+00:00 [Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/02_create_tables.sql
2024-04-06 13:20:49+00:00 [Note] [Entrypoint]: /usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/03_insert_my_mdb.sql
init
下に配置した.sql
ファイルが実行されているのが確認できました。
コンテナが起動できたら、DBに接続してデータベースやテーブルが作成されているか、初期データが投入されているか等、確認してみましょう。
$ docker container exec -it mydb mysql -uroot -prootpass
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.3.0 MySQL Community Server - GPL
Copyright (c) 2000, 2024, 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.
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| my_mdb |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.01 sec)
mysql> USE my_mdb
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> SHOW TABLES;
+------------------+
| Tables_in_my_mdb |
+------------------+
| m_region |
+------------------+
1 rows in set (0.01 sec)
mysql> SELECT * FROM m_region;
+-----------+--------------------+---------------------+---------------------+
| region_id | region_name | created_at | updated_at |
+-----------+--------------------+---------------------+---------------------+
| 1 | カントー地方 | 2024-04-06 13:20:49 | 2024-04-06 13:20:49 |
| 2 | ジョウト地方 | 2024-04-06 13:20:49 | 2024-04-06 13:20:49 |
| 3 | ホウエン地方 | 2024-04-06 13:20:49 | 2024-04-06 13:20:49 |
| 4 | シンオウ地方 | 2024-04-06 13:20:49 | 2024-04-06 13:20:49 |
+-----------+--------------------+---------------------+---------------------+
4 rows in set (0.00 sec)
初期データが投入されていますね、やったー!
さいごに
自分だけのDBが作れました!
これで、あんなテーブル定義やこんなクエリを試したい放題ですね。
細かい設定をしたい方は、conf.d
ディレクトリ(仮名)を作成してmy.cnf
を記述して配置し、/etc/mysql/conf.d
にマウントするなどしてもいいかもしれないですね!