DockerでMySQL8の環境構築でハマった話

現在自作のポートフォリオをDokerとMySQLで進めております。

そこでMySQL8から認証プラグインのデフォルトがcaching_sha2_passwordになったことでハマった話と解決策をまとめていきたいと思います。

 

MySQL8

 MySQL5.7までの認証プラグインにはmysql_native_passwordがデフォルトで使用されていましたがMySQL8より新たに追加されたcacing_sha2_passwordがデフォルトに変更されました

 

ハマった原因

 まず、Rspecを書き実行してみたら

Authentication plugin 'caching_sha2_password' cannot be loaded: /usr/lib/mysql/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory

ん????なんだこれは。

ググってみると

認証プラグインに caching_sha2_password を設定しているユーザは、接続に使用するクライアント又はコネクタ側でも caching_sha2_password をサポートしている必要があり、サポートされていない場合は、認証エラーが返されます。

なるほど。。

上記で説明した通りMySQL8から認証プラグインの仕様が変わったため エラーが返されたみたい。

 

手元でも確認

 まずコンテナを起動

$ docker-compose up -d

 Starting myapp_db_1 ... done
 Starting myapp_web_1 ... done

$ docker-compose ps

Name Command State Ports
----------------------------------------------------------------------------------------
myapp_db_1 docker-entrypoint.sh mysqld Up 0.0.0.0:3316->3306/tcp, 33060/tcp
myapp_web_1 bundle exec rails s -p 300 ... Up 0.0.0.0:3000->3000/tcp

 

MySQLサーバーにログイン

(コンテナ上で実施)

$ docker exec -it myapp_db_1 bash 

MySQLのバージョン確認

root@a15497b6aae8:/# mysql --version

mysql Ver 8.0.17 for Linux on x86_64 (MySQL Community Server - GPL)

MySQLサーバーにログイン

$ mysql -uroot -p
Enter password: (docker-compose.ymlで設定したパスワード)
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.17 MySQL Community Server - GPL

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

 

 パスワードはdocker-compose.ymlのMYSQL_ROOT_PASSWORDで設定した値です。

 

認証方法の確認

mysql> SELECT user, host, plugin FROM mysql.user; 

f:id:yamasey712:20190826145355p:plain

 やはりプラグインがcaching_sha2_passwoedになってる。

 

ではこれからこれから解決方法である既存のユーザーのプラグインmysql_native_passwordにしていく方法を書いていきます。

それと新規ユーザーのプラグインをデフォルトでmysql_native_passwordにする方法も最後に書いておきます。

 

既存ユーザーのプラグインをデフォルトにする方法

 ALTER USER で既存ユーザーのプラグインを変更できる。

mysql> ALTER USER '①'@'②' IDENTIFIED WITH mysql_native_password BY '③'

①にはユーザー名。例えば root

②にはホスト名。 例えば %

③にはパスワード。例えば new_root_password

コードにすると

mysql> ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'new_root_password'

ここで重要なのはdocker環境で設定しているユーザーのパスワードを変えた場合はdocker-compose.ymlとdatabase.ymlのパスワードも変更しておくこと。

これで再度確認すると

f:id:yamasey712:20190828211230p:plain

変更できてる。よし。

これで晴れてRspecが通るかと思ったらまさかのActiveRecord::NoDatabaseError:
Unknown database 'myapp_test'というエラー。もう心折れそうになったけど見ての通りただdatabase内にmyapp_testがなかったので

docker-compose run --rm web rake db:create

でデータベースを作成したら無事テストが実行できました。

 

では最後に新規ユーザー作成時のデフォルトプラグインmysql_native_passwoedにする方法を書いておきます。

 

新規ユーザーのプラグインを変更

①まず/etc/my.cnfに以下の内容を加える。(僕の場合はなぜか/etc/mysql/mycnfだった)

 vi my.cnf

[mysqld]

default-authentication-plugin = mysql_native_password

 ②docker-composeを使用の場合はdoker-compose.ymlに "command: --default-authentication-plugin = mysql_native_password "を加える

db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_USER: root
MYSQL_ROOT_PASSWORD: new_root_password
- '3316:3306'
volumes:
- ./db/mysql/volumes:/var/lib/mysql

 

* コピペ許して。*

③動作確認のため、一度コンテナ削除

1, docker-compose stop 

2, docker-compose rm

 ④もう1回立ち上げる

docker-compose up -d 

 ⑤MySQLにログインして以下のコマンドを実行

mysqlcreate user '①'@'②' identified by '③';

 既存ユーザ変更と入れるものは同じです。

①にはユーザー名。

②にはホスト名。 

③にはパスワード。

 コードにすると

 mysqlcreate user 'user1'@'localhost' identified by 'user1';

 

f:id:yamasey712:20190828205702p:plain

こんな感じでデフォルトのプラグインがしっかりmysql_native_passwordになったね。

 

 

最後に

 今回のこのハマりが今までの中で1番長くハマった。

やっぱりdocker環境のMySQLということで僕みたいな戦力には難しすぎました。

しかし、解決するまでに様々なMySQLの知識に触れることができました。

詰め込まないといけない知識が多すぎてパンク寸前でしたがこういうハマりを通して触れることでより頭に入る気がしました。

やはりハマっている間はクソーてなりすぎてニキビ3つはできたけど解決できたから明日には治ってるはず。

肩こったよ。プログラマに肩こりはつきものだね。就職したら絶対いい椅子買ってやる。

ってことでバイバイ。