課題
MySQL8にDocker上に構築したRailsからアクセスしようとしたら以下のようなエラーが発生して接続できなかった。
Plugin caching_sha2_password could not be loaded: /usr/lib/x86_64-linux-gnu/mariadb19/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory
注意点
本記事は caching_sha2_password
問題でハマった人向けであるが、Amazon RDS for MySQL 8.0は mysql_native_password
なのでAWSで運用してしようとしている人は異なる対応が必要なので注意(参考記事を参照のこと)
原因
8.0.4からMySQLのデフォルトの認証プラグインが caching_sha2_password
に変更になった。
LinuxではMySQLクライアントとしてMySQL互換のMariaDBが使用されるため、mysql_native_password
で接続しようとしてエラーとなっている
対応
記事での解説範囲。とりあえずこんな感じで接続できるようになった。
FROM ruby:2.6.5 WORKDIR /tmp RUN apt update && apt install -y lsb-release \ && apt remove -y libmariadb-dev-compat libmariadb-dev RUN wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-common_8.0.18-1debian10_amd64.deb \ https://dev.mysql.com/get/Downloads/MySQL-8.0/libmysqlclient21_8.0.18-1debian10_amd64.deb \ https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-community-client-core_8.0.18-1debian10_amd64.deb \ https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-community-client_8.0.18-1debian10_amd64.deb \ https://dev.mysql.com/get/Downloads/MySQL-8.0/libmysqlclient-dev_8.0.18-1debian10_amd64.deb RUN dpkg -i mysql-common_8.0.18-1debian10_amd64.deb \ libmysqlclient21_8.0.18-1debian10_amd64.deb \ mysql-community-client-core_8.0.18-1debian10_amd64.deb \ mysql-community-client_8.0.18-1debian10_amd64.deb \ libmysqlclient-dev_8.0.18-1debian10_amd64.deb
解説
対策は2案
- MySQL8対応のディストリビューションを使ってビルドする
- Linux上にMySQL8系のライブラリをインストールする
1はUbuntuのeoanがMySQL8に対応していたのでそれをビルドイメージにすればいけそうな気がする。 今回はDockerHubにあるRubyイメージからRails用イメージを構築していきたかったので2で考えてみる。
Dockerファイルを作る
1. ベースイメージ
Rubyのベースのディストリビューションもいろいろあるのだけど標準のにしてみた。このimageはDevian 10 buster
をベースにしている。
FROM ruby:2.6.5
2. 依存ライブラリの追加と競合ライブラリの削除
lsb-release
がないと怒られるので追加する。
同時に、mariadb系のライブラリ系が残っているとmysql8系のライブラリがコンフリクトして入れられないので削除する
libmariadb3
と mariadb-common
は削るとRails(mysql2)から接続できなくなるので注意。ただしmysqlコマンドはなくても通る。
RUN apt update && apt install -y lsb-release \ && apt remove -y libmariadb-dev-compat libmariadb-dev
MySQL 8のライブラリをダウンロード
最新バージョンのパッケージとなるとaptでは配布されていないため、 MySQLのホームページからクライアント系のパッケージをダウンロードしてインストールする。
必要なものは以下の通り。クライアント系は全部入れておく。もしかしたら不要なものも混ざっているかもしれない。
RUN wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-common_8.0.18-1debian10_amd64.deb \ https://dev.mysql.com/get/Downloads/MySQL-8.0/libmysqlclient21_8.0.18-1debian10_amd64.deb \ https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-community-client-core_8.0.18-1debian10_amd64.deb \ https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-community-client_8.0.18-1debian10_amd64.deb \ https://dev.mysql.com/get/Downloads/MySQL-8.0/libmysqlclient-dev_8.0.18-1debian10_amd64.deb
dpkgコマンドで入れる。
RUN dpkg -i mysql-common_8.0.18-1debian10_amd64.deb \ libmysqlclient21_8.0.18-1debian10_amd64.deb \ mysql-community-client-core_8.0.18-1debian10_amd64.deb \ mysql-community-client_8.0.18-1debian10_amd64.deb \ libmysqlclient-dev_8.0.18-1debian10_amd64.deb
以上。
あとは普通にRaisのDockerfileを作ればよい(省略)。
安易に mysql_native_password
に逃げたくなかったので時間をかけて調べたものの、caching_sha2_password
がAWSで使えないということが判明して以降はただの意地であった。