Rails 6 + MySQL8.0 + Docker 環境でMySQLを日本語化


初学者向けの記事です。
私の備忘録として残します。

docker-compose.yml上で2つのことをしようとしてハマった

・「MySQL8.0の認証方法に対応」

・「MySQLの文字コードを変更」

これを同時にやろうとしてハマりました。

やりたいこと1 「MySQLの認証方法変更」

MySQL8.0から

command: --default-authentication-plugin=mysql_native_password

を追加する必要がありました。

コード全体を確認 (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: password
    web:
        build: .
        command: bundle exec rails s -p 3000 -b '0.0.0.0'
        volumes:
            - ./src:/app
        ports:
            - "3000:3000"
        depends_on:
            - db

やりたいこと2 MySQLの文字コードをutf8mb4に変えたい

また、dockerでmysqlの文字コードを日本語対応のものに変更しようとすると、次のようなコマンドを打つ必要があるとわかりました。
(imageを引っ張ってくるとデフォルトの文字コードは「latin1」でした)

command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

で、「commandを2つ書けば良いんだな」と思って調整していたのですが、うまくいきません。
というのも、docker-compose.ymlのcommandは「1つしか書けない」からなんですね。

Run a one-off command on a service

参考文献

思いついた解決策1(失敗):1つの長いcommandにする

下記リンクを参考に長い1つのcommandを作ろうと思いましたが失敗しました。
もう少し粘れば行ける気がするのですが、そもそも長いコマンドはあまり美しくないかも・・・と思って解決策2を試したところ、すんなり解決しました。

参考リンク

思いついた解決策2(成功):localのmy.cnfをmysqlのdbコンテナにコピーする

まずlocalの適当な場所にmy.cnfを作ります。
そこにdbコンテナのmy.cnfをコピーして、先ほどコマンドでやりたかったことを追記します。

そしてdocker-compose.ymlを編集
1、commandを削除(全てmy.cnfに書いたので)
2、volumesに下記の一行追記

- ./src/db/my.cnf:/etc/mysql/my.cnf

コード全体を確認 (docker-compose.yml)
version: '3'
services:
    db:
        image: mysql:8.0
        volumes:
            - ./src/db/mysql_data:/var/lib/mysql
            - ./src/db/my.cnf:/etc/mysql/my.cnf
        environment:
            MYSQL_ROOT_PASSWORD: password
    web:
        build: .
        command: bundle exec rails s -p 3000 -b '0.0.0.0'
        volumes:
            - ./src:/app
        ports:
            - "3000:3000"
        depends_on:
            - db

おわり

これで無事文字コードの置き換えとMySQL8.0の認証を同時に行うことができました。
Rails 6 + MySQL8.0 + Dockerで開発をすれば誰でもこの状況になる気がするので、みなさん普通に解決してるんですよね。
私は1時間以上かかりました。

これからも精進します。
何か間違いがあればご指摘いただけますと幸いです。

備考

docker-compose.ymlを書き換えた時はdocker-compose downとupだけで動作確認できます。
私はよくわからなくて途中まで毎回buildしていました。