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 - GPLCopyright (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で設定した値です。
認証方法の確認
やはりプラグインが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のパスワードも変更しておくこと。
これで再度確認すると
変更できてる。よし。
これで晴れて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:environment:- '3316:3306'volumes:
* コピペ許して。*
③動作確認のため、一度コンテナ削除
1, docker-compose stop
2, docker-compose rm
④もう1回立ち上げる
docker-compose up -d
⑤MySQLにログインして以下のコマンドを実行
mysql> create user '①'@'②' identified by '③';
既存ユーザ変更と入れるものは同じです。
①にはユーザー名。
②にはホスト名。
③にはパスワード。
コードにすると
mysql> create user 'user1'@'localhost' identified by 'user1';
こんな感じでデフォルトのプラグインがしっかりmysql_native_passwordになったね。
最後に
今回のこのハマりが今までの中で1番長くハマった。
やっぱりdocker環境のMySQLということで僕みたいな戦力には難しすぎました。
しかし、解決するまでに様々なMySQLの知識に触れることができました。
詰め込まないといけない知識が多すぎてパンク寸前でしたがこういうハマりを通して触れることでより頭に入る気がしました。
やはりハマっている間はクソーてなりすぎてニキビ3つはできたけど解決できたから明日には治ってるはず。
肩こったよ。プログラマに肩こりはつきものだね。就職したら絶対いい椅子買ってやる。
ってことでバイバイ。