Dockerを使ってMySQLのセットアップをしようとして初期化スクリプトをdocker-entrypoint-initdb.d
にぶち込んだはいいけど
なんかスクリプトが実行されない…
imageをガッツリ削除して一からやり直すと、うまくいく。なぜ。
なぜ実行されないのか
MySQLのDockerイメージでは、docker-entrypoint-initdb.dディレクトリ内のスクリプトは、データベースが存在していない(つまり初回起動時)にのみ実行されます。
この問題は、データベースファイルをホストマシンと同期(バインドマウント)している場合に起こりやすいです。 同期されたデータベースファイルが存在すると、Dockerはデータベースが既に初期化されていると判断し、初期化スクリプトの実行をスキップします。
解決策は?
名前付きボリュームを使う
名前付きボリュームを使う方法
以下のdocker-compose.ymlサンプルは、名前付きボリュームを使用してMySQLデータベースをセットアップする方法を示しています。この設定では、MySQLの設定ファイル、初期化スクリプト、およびデータベースファイルを名前付きボリュームに保存します。
db: container_name: mysql-local image: mysql:8 volumes: - ./docker/local/db/my.cnf:/etc/mysql/conf.d/my.cnf - mysql-local:/var/lib/mysql - ./docker/local/db/initDb.sql:/docker-entrypoint-initdb.d/initDb.sql # (中略) volumes: mysql-local:
この構成では、mysql-local
という名前のボリュームがMySQLのデータディレクトリ/var/lib/mysql
にマッピングされ、データの永続化を保証します。
加えて、カスタムのMySQL設定ファイルと初期化スクリプトが適切にコンテナに適用されます。
クリーンアップ
docker-compose down --volume
コマンドを使って、必要に応じて作成した名前付きボリュームを綺麗に消し去りましょう。
ただし、この操作はすべてのデータを削除するため、必要なデータが失われないように注意してください。