Railsを気軽に試すために用意していたリポジトリをクローンしたら、MySQLのdbコンテナが起動しないという思わぬエラーに遭遇しました。次同じような状況が発生した際にすぐに対応できるよう、備忘録として記録しておきます。
概要
RailsのプロジェクトをDocker環境で動かそうと、用意してあったリポジトリをローカルにクローンしました。
docker compose build
→ docker compose up
の流れで起動したところ、dbコンテナだけが落ちてしまいました。
環境
- MacOS Sonoma 14.2
- Docker Desktop for mac
- MySQL 9.1.0
- ruby 2.7.4
- rails 6.1.7
解決手順
docker logs <dbコンテナ名>
でログを確認。表示されたログの中で以下の出力に着目。
mysqld: Table 'mysql.plugin' doesn't exist
[ERROR] [MY-010735] [Server] Could not open the mysql.plugin table. Please perform the MySQL upgrade procedure.
調べてみると、MySQLのデータディレクトリに不整合が生じている可能性が高いとのこと。
docker-compose.ymlファイルのdbサービスのボリュームからデータディレクトリ(./tmp/db
)を探し、そのデータディレクトリ配下を確認すると、複数のファイルが格納されていました。
services:
db:
volumes:
- ./tmp/db:/var/lib/mysql
これが原因っぽい?ということで、とりあえず初期化を実施してみることに。
1. プロジェクトのルートディレクトリに移動
2. コンテナを停止
$ docker compose down
3. データディレクトリを削除
$ rm -rf ./tmp/db
4. コンテナを再起動
$ docker compose up -d
今回はこの手順で無事コンテナが起動しました。
なぜこうなったか?
結論から言うと、上述の通り、リポジトリにMySQLのデータディレクトリ (./tmp/db
) が含まれていたためです。
MySQLは起動時、/var/lib/mysql
にシステムテーブル(mysql.plugin
, mysql.user
など)を作成するようです。
ここに中途半端なデータや、別の環境で作られたデータ(バージョン違いを含む)が存在すると、起動時に「テーブルが存在しない or フォーマットが違う」と怒られてしまいます。
今回は、クローンしたリポジトリの ./tmp/db
に MySQL データが残っていた → それをコンテナにマウント → MySQL が壊れた状態で起動しようとして失敗、という流れでした。
どうしてリポジトリにそんなファイルが入ってた?
これは「ローカルの生成物を誤ってGitにコミットしてしまった」という私のミスです。
本来、./tmp/db
のようなコンテナが起動時に生成するデータはGit管理に含めるべきではなく、.gitignore
に入れておくのが正解です。
.gitignore
には以下を追加しておきます。
/tmp/db
まとめ
- リポジトリをクローンしてDocker環境を起動したところ、MySQLが「Table 'mysql.plugin' doesn't exist」エラーで起動しなかった
- 原因は、リポジトリ内にMySQLのデータディレクトリ(
./tmp/db
)が含まれていたこと - 不要なデータを削除して再度コンテナを起動することで解決
- 本来は
.gitignore
にtmp/db
を追加して、データディレクトリの内容がコミットされないようにしておく必要があった
補足
今回に限った話ではないですが、削除操作時の基本として、削除する前にデータの中身を確認しておきましょう。
./tmp/db
のような一時ファイルやキャッシュデータであれば、基本的に削除しても問題ないことが多いですが、必要に応じてバックアップを取っておくと安心できるかと思います。