今回の事象について
DockerでMySQLの起動時にデータベースおよびテーブルを作成するようにしました。
docker-entrypoint-initdb.dに作成したSQLファイルを配置しましたが、MySQLにテーブルが作成されていませんでした。
環境
・Docker 20.10.24
・PHP 8.1
・MySQL 8.0
ディレクトリ構成
.
├── mysql
│ ├── conf.d
│ │ └── my.cnf
│ │── data
│ │── init
│ │ └── create_test_db.sql
│ │ └── create_users_table.sql
│ ├── Dockerfile
├── php-apache
│ └── 000-default.conf
│ └── Dockerfile
│ └── php.ini
├── docker-compose.yml
└── src
└── info.php
※php-apacheディレクトリ内の設定ファイルは今回の事象には関係ないため、ファイルの内容は割愛します。
docker-compose.ymlの内容
version: '3'
services:
php:
container_name: php
build: ./php-apache
ports:
- 80:80
volumes:
- ./src:/var/www/login
working_dir: /var/www/login
mysql:
container_name: mysql
build: ./mysql
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: testDB
TZ: 'Asia/Tokyo'
volumes:
- ./mysql/conf.d:/etc/mysql/conf.d
- ./mysql/data:/var/lib/mysql
- ./mysql/init:/docker-entrypoint-initdb.d
ports:
- 3306:3306
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
MySQL用Dockerfileの内容
FROM mysql:8.0
RUN lower_case_table_names=0
create_test_db.sqlの内容
CREATE DATABASE IF NOT EXISTS `testDB` COLLATE `utf8mb4_unicode_ci`;
GRANT ALL ON *.* TO root@'%'
create_users_table.sqlの内容
DROP TABLE IF EXISTS `testDB`.`users`;
CREATE TABLE `testDB`.`users`(
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`email` VARCHAR(255) NOT NULL,
`password` VARCHAR(255) NOT NULL,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`is_deleted` BOOLEAN NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
);
Docker起動からMySQL接続まで
$ docker-compose up -d --build
$ docker exec -it mysql bash
$ mysql -u root -p
※mysql接続時のパスワードはyamlファイルで設定したものを入力します。
DBとテーブルの確認
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testDB | ← おk
+--------------------+
5 rows in set (0.01 sec)
mysql> use testDB;
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;
Empty set (0.00 sec) ← ぴえん
create_users_table.sqlで作成したusersテーブルが反映されていません。
原因と対策
ホスト側のデータボリュームにDBに関する情報が残っていたことが原因であったため、mysql/data配下のディレクトリ及びファイルを全削除し、再度コンテナを立ち上げます。
# コンテナの停止
$ docker-compose down
# データボリューム用のディレクトリ及びファイルを全削除
$ rm -rf mysql/data/*
↑このときに本当に全削除するか聞いてくるので「y」を指定する
# コンテナを立ち上げる
$ docker-compose up -d --build
テーブルの確認
# mysqlコンテナに入る
$ docker exec -it mysql bash
# mysqlに接続
$ mysql -u root -p
mysql> use testDB;
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_testdb |
+------------------+
| users | ← おk
+------------------+
1 row in set (0.00 sec)
mysql> show columns from users;
+------------+--------------+------+-----+-------------------+-----------------------------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-------------------+-----------------------------------------------+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(50) | NO | | NULL | |
| email | varchar(255) | NO | | NULL | |
| password | varchar(255) | NO | | NULL | |
| created_at | datetime | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
| updated_at | datetime | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED on update CURRENT_TIMESTAMP |
| is_deleted | tinyint(1) | NO | | 0 | |
+------------+--------------+------+-----+-------------------+-----------------------------------------------+
7 rows in set (0.00 sec)
無事にusersテーブルが作成されました。
まとめ
ホスト側のデータボリュームにDB情報が残り続けていると変更が効かないため、データボリュームを全削除してからコンテナを起動させましょう。
参考