【Docker】MySQL コンテナの initdb が読み込めない
Skrumエンジニアの多賀です。
Docker の MySQL イメージには、Docker コンテナ作成時に特定のディレクトリ内の SQL を自動的に読み込んでくれる仕組みがあります。
docker-entrypoint-initdb.d を任意のローカルディレクトリにマウントすると、当該ローカルディレクトリの直下に置いた .sql ファイルを自動的に読み込んでくれます。自分で mysql コマンドを実行する必要がないのでとても便利です。
私の環境では、docker-compose.yml に下記のように記載しています。プロジェクトフォルダ直下の docker ディレクトリに initdb というディレクトリを作って、docker-entrypoint-initdb.d をマウントしています。
mysql:
image: mysql:8.0
ports:
- "3306:3306"
volumes:
- ./docker/initdb:/docker-entrypoint-initdb.d
全体のディレクトリ構成は下記のようになります。
├ root
├ docker-compose.yml
└ docker
└ initdb
├ example1.sql
├ example2.sql
├ example3.sql
└ example4.sql
initdb の SQL が読み込めない
イメージ作成・初回コンテナ起動時には initdb ディレクトリ下の SQL ファイルを読み込むことができ、MySQL コンテナの DB には SQL ファイルに記述された DB スキーマやテストデータが自動で反映されました。
その後 DB スキーマに大きな変更があり、SQL ファイルを読み込み直したいタイミングがありました。そこで、initdb ディレクトリ下の SQL ファイルを別の SQL ファイルに置き換えて下記コマンドでコンテナを再作成しました。
docker-compose down
docker-compose up
しかし、新しい SQL ファイルの内容が DB に反映されません。
コンテナを削除してもボリュームは削除されない
Docker volumes とは Docker のコンテナ内で作成したデータを永続化するための場所です。
コンテナを削除してもボリュームは削除されないのです。コンテナを削除( docker-compose down )した後に、コマンド( docker volume ls )でボリュームを確認すると、当該コンテナで使用していたボリュームは削除されていないことがわかります。
つまり、コンテナを再作成( docker-compose up )すると、既存のボリュームがマウントされるので、initdb 下のファイルが読み込まれないため新しい SQL ファイルの内容が DB に反映されなかったのです。
ボリュームを削除する
ローカルPC(ホスト)のファイルを更新した場合は、ボリュームを削除しマウントし直す必要があります。
docker volume ls
docker volume rm {VOLUME NAME}
docker volume ls
docker-compose up
MySQL コンテナの DB を確認すると新しい SQL ファイルの内容が反映されていることが確認できると思います。