docker composeが起動できなくなった話。

##はじめに
docker compose upでMySQLのコンテナが急に起動しなくなった時のことと、その解決策について備忘録として投稿します。

##開発環境
docker [20.10.6]
ruby [2.7.3]
ruby on rails [6.1.4.1]
MySQL [8.0]

##事象について
railsアプリケーション開発中に、新たにモデルを追加したので、以下を実行。

~~~bash:terminal
docker compose down #コンテナを削除
⠿ Container rails_portfolio_web_1  Removed                                                                                                                                                            0.2s
⠿ Container rails_portfolio_db_1   Removed                                                                                                                                                            0.1s
⠿ Network rails_portfolio_default  Removed

docker compose up -d #コンテナを作成し、デタッチ起動
⠿ Network rails_portfolio_default  Created                                                                                                                                                            0.0s
⠿ Container rails_portfolio_db_1   Started                                                                                                                                                            0.6s
⠿ Container rails_portfolio_web_1  Started
~~~

で、ブラウザでローカル環境をリロードすると以下のエラーに遭遇。
![スクリーンショット 2021-10-19 21.00.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653944/1961d2ea-db1e-9e66-46b4-eaff8330b732.png)
どうやら、MySQLが正常に起動していない模様。
ターミナルに戻り、以下のコマンドで起動中のコンテナの状態を確認したところ、、、

~~~bash:terminal
docker compose ps
NAME                    COMMAND                  SERVICE             STATUS              PORTS
rails_portfolio_db_1    "docker-entrypoint.s…"   db                  exited (1)
rails_portfolio_web_1   "bundle exec rails s…"   web                 running             0.0.0.0:3000->3000/tcp, :::3000->3000/tcp
~~~
dbのSTATUSがexit(1)となっていて、ポートも閉じていました。

原因確認のため、以下のコマンドでログの情報を確認します。

~~~bash:terminal
docker compose logs
db_1   | 2021-10-18 14:51:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.25-1debian10 started.
db_1   | 2021-10-18 14:51:36+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
db_1   | 2021-10-18 14:51:36+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.25-1debian10 started.
db_1   | 2021-10-18T14:51:36.743475Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.25) starting as process 1
db_1   | 2021-10-18T14:51:36.758094Z 0 [Warning] [MY-010159] [Server] Setting lower_case_table_names=2 because file system for /var/lib/mysql/ is case insensitive
db_1   | 2021-10-18T14:51:36.780195Z 1 [ERROR] [MY-011011] [Server] Failed to find valid data directory.
db_1   | 2021-10-18T14:51:36.781053Z 0 [ERROR] [MY-010020] [Server] Data Dictionary initialization failed.
db_1   | 2021-10-18T14:51:36.781227Z 0 [ERROR] [MY-010119] [Server] Aborting
db_1   | 2021-10-18T14:51:36.782964Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.25)  MySQL Community Server - GPL.
~~~
エラー個所を発見！

~~~bash
db_1   | 2021-10-18T14:51:36.780195Z 1 [ERROR] [MY-011011] [Server] Failed to find valid data directory.
db_1   | 2021-10-18T14:51:36.781053Z 0 [ERROR] [MY-010020] [Server] Data Dictionary initialization failed.
~~~
「有効なデータディレクトリが見つけることができませんでした。」
「データディレクトリの初期化に失敗しました。」
という２つのエラーが発生していました。

##解決方法
MySQLのデータディレクトリの中身が存在している場合は、エラーが発生してしまうため、**実行前にデータディレクトリの中身を全て削除しておく必要があります。**

データディレクトリを削除するとDBのデータは、削除されてしまうため、必要があれば、事前にバックアップが必要です。

ちなみに、私の場合、docker-compose.ymlにデータ永続化のために、ボリュームマウントしていたため、docker compose downでコンテナを削除した後もデータディレクトリの中身が保持されていました。

~~~yml:docker-compose.yml
version: '3'
services:
  db:
    image: mysql:8.0
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - ./src/db/mysql_data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: <%= Rails.application.credentials.database_yml[:sql_password] %>
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    # stdin_open: true
    # tty: true 
    volumes:
      - ./src:/app
    ports:
      - "3000:3000"
    environment:
      # RAILS_ENV: development
      EDITOR: vim
    depends_on:
      - db
~~~
以下のコマンドでボリュームごとコンテナを削除します。

~~~bash
docker compose down -v
~~~

コンテナ側に合わせて、ローカルでもdb/mysql_dataフォルダーを削除します。
![スクリーンショット 2021-10-21 16.35.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653944/e52cd71d-3d2b-f2e4-44c6-f74f94af10d0.png)

docker composeでコンテナを再起動します。

~~~bash:terminal
docker compose up -d
⠿ Network rails_portfolio_default  Created                                                                                                                                                            0.0s
⠿ Container rails_portfolio_db_1   Started                                                                                                                                                            0.6s
⠿ Container rails_portfolio_web_1  Started
~~~
その後、起動中のコンテナの状態を確認すると、、、

~~~bash:terminal
docker compose ps
NAME                    COMMAND                  SERVICE             STATUS              PORTS
rails_portfolio_db_1    "docker-entrypoint.s…"   db                  running             3306/tcp, 33060/tcp
rails_portfolio_web_1   "bundle exec rails s…"   web                 running             0.0.0.0:3000->3000/tcp, :::3000->3000/tcp
~~~
無事、MySQLのコンテナが起動しました！！
##参考
[MySQLが”Failed to find valid data directory”エラーで起動できない](https://worktoolsmith.com/mysql-error-01/)
[【Docker】MySQLイメージでコンテナを作り直しても初期化しない理由はなんでしょうか？](https://teratail.com/questions/192590)
[docker + mysql が接続できない... Access denied for user 'homestead'@'172.20.0.1' (using password: YES)](https://qiita.com/fumi_042/items/7d1c14e335ab1c226e0f)