Laradockで任意データベース作成・追加 - Laradock mysql - 少しdocker
経緯
LaradockでAPIサーバーとして使うLaravel 8.xを立ち上げるメモでは、一つのLaradock環境に複数のプロジェクトを立ち上げ、同時に開発可能な環境を構築しています。(主にこの辺の内容)
そして、他の関連記事でプロジェクトの追加を行っているのですが、一つ、スルーしている点があります。
利用するデータベースをプロジェクトごとに作成せずに共有しているという点です。
個人的には、phpMyAdminで追加しています。そう頻繁に行うことではないので、それで十分と思っていましたが、実際にやろうとすると少し面倒です。
Laradockたるもの、データベースの追加くらい用意してあるだろうと思って、laradock/mysql/*
らへんを探ってみたら、、、
発見しました。
というわけで確認した内容を記事に残しておきます。
Laradockの任意データベース作成・追加方法
以下がすべてです。
laradock/mysql/docker-entrypoint-initdb.d/createdb.sql.example
このcreatedb.sql.example
にたどり着けたものだけが、Laradockにおける複数データベース作成・追加の方法について知ることができるでしょう(たぶん)。
以降は、ほぼ、説明の翻訳のようなものですが、記載しておきます。
方法1:Laradock環境の新規構築
定番なやつですが、createdb.sql.example
をcreatedb.sql
にリネームすることで有効になります。
以下のような記述例がありますので、これを基に任意のデータベース名に書き換えて記述するのがよいでしょう。
#CREATE DATABASE IF NOT EXISTS `dev_db_1` COLLATE 'utf8_general_ci' ;
#GRANT ALL ON `dev_db_1`.* TO 'default'@'%' ;
例えば、dev_app01
というデータベースにするなら、データベース名2か所を書き換えます。
CREATE DATABASE IF NOT EXISTS `dev_app01` COLLATE 'utf8_general_ci' ;
GRANT ALL ON `dev_app01`.* TO 'default'@'%' ;
必要なら、ユーザーを変更しても良いでしょう。
ただし注意点があります。
このSQLスクリプトは、dockerコンテナが開始されたタイミングで、
MySQLのデータ管理ディレクトリが存在しない時にだけ、自動で実行されます。
つまり、Laradockで初めてdocker-compose up -d mysql
的なことをした場合にのみ自動実行されます。
つまりつまり、追加はできません。
方法2:Laradock環境の再構築
自動実行したかったら、MySQLのデータ管理ディレクトリを消せ、そういうことです。もはや脅迫です。
MySQLのデータ管理ディレクトリとは、$DATA_PATH_HOST/mysql
のことです。
$DATA_PATH_HOST
は、laradock/.env
に記載されています。
# Choose storage path on your machine. For all storage systems
DATA_PATH_HOST=~/.laradock/data
Windowsの場合、C:\Users\ユーザー名\.laradock\data
です。
createdb.sql
を準備した上で、以下の手順を踏むとcreatedb.sql
に記載のとおりにデータベースが作成されます。
- laradockの停止(down)
laradock> docker-compose down
- mysqlディレクトリ削除
~/.laradock/data
のmysql
を手動で削除、もしくはリネーム
→mysql.bak
にリネームしておいて、不要になったら消す、とかでも良いかと。 - laradockの開始(up)
環境に応じて以下のように。laradock> docker-compose up -d nginx mysql
これで、従来どおりのdefault
データベースと、createdb.sql
に記載したデータベースが作成されます。
方法3:createdb.sqlを手動実行
もし、MySQLのデータ管理ディレクトリが存在していて、
それを消したくないと望むなら、手動で実行できます。
というわけで、データベースを追加したいなら、手動で追加しなさいということです。
createdb.sql
を用意することで記録として残せるのは利点ですが、結局手動です、手動なのです。
手動の実行方法も同スクリプトに書いてありますが、一応記載します。
mysqlが起動している状態で操作します。
- mysqlコンテナに接続
laradock> docker-compose exec mysql bash
- スクリプト実行rootユーザーのパスワードの入力が求められます。
root@3b248e76c0ba:/# mysql -u root -p < /docker-entrypoint-initdb.d/createdb.sql Enter password:
laradock/.env
のMYSQL_ROOT_PASSWORD
で設定しているパスワードを入力します。 - mysqlコンテナから切断
root@3b248e76c0ba:/# exit
手動実行ということで面倒かと思いきや、これだけです。
CREATE DATABASE
コマンドに、IF NOT EXISTS
の記述があるため、同じ名前のデータベースがすでに存在する場合、該当のデータベースの作成は行われません。
データベースを追加したかったら、createdb.sql
にコマンドを追記してスクリプトを手動実行すれば良い、というお話でした。
補足:Dockerのmysqlについて少し
docker-entrypoint-initdb.dとは何か
/docker-entrypoint-initdb.d/createdb.sql
の実行は、どこの仕組みで、どのように行われるのか。
という点について蛇足補足します。
結論を先に書くと、
/docker-entrypoint-initdb.d/createdb.sql
の実行は、DockerのMySQLの公式イメージの仕組みにより、docker-entrypoint.sh
で行われます。
Laradockは、このようにPHP開発環境の構築に利用できるDockerイメージがあらかじめ選定されており、それらを簡単に利用できるような仕組みです。
Dockerあるいはdocker-composeの面では、いわばノウハウの宝庫です…、いや、宝庫は言い過ぎでかもしれません。洗練されてシンプルな組み合わせになっているので、掘り下げないと宝にはたどり着きません。言い換えるとするなら、ノウハウの宝庫の入口です(きっと)。
選定されているものを確認したり、Dockerfileの内容を確認するだけでも勉強になる、と思います。(docker-composeを組む際に、Laradockのdocker-compose.ymlを参考にさせていただいたりしました。)
docker-entrypoint-initdb.dを紐解いてみる
補足として言いたかったのは前項の点だけなのですが、せっかくなので紐解いてみます。
-
docker-entrypoint-initdb.dという名前
まず、docker-entrypoint-initdb.d
という名前ですので、「dockerの仕組みに依存したもの」
ということがすぐに分かります。 -
laradock/mysql/Dockerfileの内容
次に、laradock/mysql/Dockerfile
の内容を確認すると、docker-entrypoint-initdb.d
に対して何も記述がないことから、mysqlのDockerイメージの仕組みをそのまま利用しているということが分かります。 -
実際のDockerイメージ
DockerfileのFROM mysql:${MYSQL_VERSION}
という記述で、実際のDockerイメージが分かります。
また、${MYSQL_VERSION}
はlaradock/.env
に記載のMYSQL_VERSION=latest
が展開されます。
というわけで、Laradockのmysqlのイメージは、mysql:latest
が基になっていることが分かります。 -
docker hub
docker hubで確認してみます。
https://hub.docker.com/_/mysql -
mysqlイメージのDockerfile
docker hubのmysqlの画面の「Supported tags and respective Dockerfile links」のlatest
をクリックすると、mysql:latest
のDockerfileを閲覧できます。話の元になっているディレクトリの
docker-entrypoint-initdb.d
という名称からアタリをつけて、ENTRYPOINTの設定を確認します。ENTRYPOINT ["docker-entrypoint.sh"]
実行されているシェルのファイル名が特定できました。
-
mysqlイメージのentrypoint
docker-entrypoint.sh
を確認します。
(latestのバージョンが8.0の場合)画面上部にmysql/8.0/Dockerfile.debian
という表示中のパスの表記があるので、8.0
のリンクをクリックしてファイル一覧を表示します。
続いてdocker-entrypoint.sh
のリンクをクリックして開きます。 -
docker-entrypoint.shの内容
このシェルの内容を読み取るのは大変なのでポイントだけ抜き出します。ざっと眺めると、以下のような箇所があると思います。
# there's no database, so it needs to be initialized if [ -z "$DATABASE_ALREADY_EXISTS" ]; then
「MySQLのデータ管理ディレクトリが存在しない時にだけ自動実行」という点は、ここの処理に則った仕組みということのようです。
そして、上記のif文の中に、以下のような記述があります。
docker_process_init_files /docker-entrypoint-initdb.d/*
他に
docker-entrypoint-initdb.d
内のファイルにアクセスしている箇所がないので、createdb.sql
はここで処理されるということになります。docker_process_init_files
を確認します。docker_process_init_files() { : *.sql) mysql_note "$0: running $f"; docker_process_sql < "$f"; echo ;;
docker-entrypoint-initdb.d
内のファイルすべてをループで処理し、特定の拡張子のファイルに対して何らかの処理を行っているようです。
createdb.sql
は、ファイルの内容が読み取られ、標準入力経由でdocker_process_sql
に渡されています。docker_process_sql
を確認します。# Execute sql script, passed via stdin # usage: docker_process_sql [--dont-use-mysql-root-password] [mysql-cli-args] # ie: docker_process_sql --database=mydb <<<'INSERT ...' # ie: docker_process_sql --dont-use-mysql-root-password --database=mydb <my-file.sql docker_process_sql() {
処理の説明が記述されていました。ここで標準入力経由でSQLスクリプトを実行するようです。
createdb.sql
はここで実行される、ということです。
laradockのdocker-compose.yml
ちなみに、laradockのdocker-compose.ymlの以下の記述も関連して重要な点ですので、追加で記載しておきます。ボリュームマウントしています、というお話です。
### MySQL ################################################
mysql:
:
volumes:
- ${DATA_PATH_HOST}/mysql:/var/lib/mysql
- ${MYSQL_ENTRYPOINT_INITDB}:/docker-entrypoint-initdb.d
:
補足:複数のLaradock
ついでにもう一つ補足です。
方法2で出てきた以下について。
# Choose storage path on your machine. For all storage systems
DATA_PATH_HOST=~/.laradock/data
自身の開発環境では複数のLaradock環境を動かしています。
業務用Laradockと、検証用Laradock、という感じです。
Workspace的に、関係のないプロジェクトを混在させないようにしたい、ということでそうしているのですが、その際に行っているのが、DATA_PATH_HOSTの個別設定です。
例えば、以下のように分けておけば、検証用Laradockは細かいことを気にせずに気軽にスクラップ&ビルドやら再構築やらを行えます。
- 業務用Laradock:
DATA_PATH_HOST=~/.laradock/data1
- 検証用Laradock:
DATA_PATH_HOST=~/.laradock/data2
今回のcreatedb.sql
の説明を見て、検証用のLaradockであれば、予め余分にデータベースを作っておいて好きに切り替えるなんてのもありかな、などと考えています。
まぁ、php artisan migrate:fresh --seed
すれば済む話なので、default
データベース1つで十分かもしれませんが、あるに越したことはない、ということで。
おわりに
今まで、Laradockでのデータベースの追加はphpMyAdminで行っていたのですが、今後はこの方法(方法3)で追加しようと思います。もっと早くちゃんと調べておくべきでした。
こんなところで。
Discussion