前人未踏の領域へ WEB・インフラ・プログラミング全般編

フロントエンド、バックエンド、インフラ、言語など、アプリ開発、IOT以外の記録

LinuxベースのDockerからMySQL 8.0に接続するための記述

課題

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案

  1. MySQL8対応のディストリビューションを使ってビルドする
  2. 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系のライブラリがコンフリクトして入れられないので削除する

libmariadb3mariadb-common は削るとRails(mysql2)から接続できなくなるので注意。ただしmysqlコマンドはなくても通る。

RUN apt update && apt install -y lsb-release \ 
    && apt remove -y libmariadb-dev-compat libmariadb-dev

MySQL 8のライブラリをダウンロード

最新バージョンのパッケージとなるとaptでは配布されていないため、 MySQLのホームページからクライアント系のパッケージをダウンロードしてインストールする。

dev.mysql.com

必要なものは以下の通り。クライアント系は全部入れておく。もしかしたら不要なものも混ざっているかもしれない。

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_passwordAWSで使えないということが判明して以降はただの意地であった。

参考

/* Responsive: yes */