Dockerで稼働するMySQLの文字コードを設定する話
概要
ASP.NET Core MVCを使用した簡単なことをTwitterにつぶやくモノを作っていて
開発環境のDBにDocker上で稼働するMySQLを使っています。
つぶやく際にTweet内容をDBに登録しており文字化けが発生してしまったのでMySQLの文字コードを変更して対応したメモです。
目次
環境
- MacOS Mojave Version 10.14.3
- .Net Core SDK Version 2.2.104
- Docker Version 18.09.2
- Docker image : MySQL 5.7(公式)
参考サイト様
- MySQL 文字コードをUTF8に変更する - わすれないうちにメモしよう
- MySQL :: MySQL 5.7 Reference Manual :: 10.5 Configuring Application Character Set and Collation
- MySQL :: MySQL 5.7 Reference Manual :: 10.4 Connection Character Sets and Collations
- MySQL :: MySQL 5.7 Reference Manual :: 5.1.6 Server Command Options
- docker logs で表示されるログの保存場所とローテート方法 - Qiita
- MySQL 文字コード確認 - Qiita
- Docker Hub
- MySQLのmy.cnfファイルサンプル - 世界の一部
事象
下記のようなFormにツイート内容を記入しツイートします。
その過程でツイートの記録を残すためDB上にデータを残しています。
しかし、DBに登録されたデータが文字化けしてしまうと言う事象です。
参考画像
下記のようなFormからツイート内容を登録します。DBデータ
上記の画面から登録/更新を行ったデータが下記です。
(まあ、登録時点で文字化けしてるので更新もクソもないですが...)
mysql> select * from TODOAPP.Task; +----+---------+-------+---------------+ | id | task | state | TweetResultid | +----+---------+-------+---------------+ | 5 | ? | 1 | 1 | | 6 | ? | 1 | 1 | | 7 | ? | 0 | 1 | | 8 | ? | 0 | 1 | | 9 | ??????? | 0 | 2 | +----+---------+-------+---------------+
- 該当のツイート
ツイート+該当データをDBに登録すると言う動作なので問題ないですが
該当データを更新する際にDBからデータを取得すると文字化けしたデータしか取得できないので下記のような文字化けしたツイートになってしまいます。┬[○] ?
— あとらす (@Lychee_jam) 2019年3月2日
├[○] ?
├[] ?
└[] ?#3分間本気出す
原因
DcokerのMySQL公式イメージを使用しているのですがMySQLの設定を何もしていなかったために文字コード設定が下記の様に初期値となっていました。
mysql> show variables like '%char%'; +--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | latin1 | | character_set_connection | latin1 | | character_set_database | latin1 | | character_set_filesystem | binary | | character_set_results | latin1 | | character_set_server | latin1 | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+
参考:Latin-1について
対策
通常であればmy.cnf
で文字コードを指定して、再起動してやればいいのですがDockerで動かしてるのでそうも行きません。
(コンテナ内でvi
とかnano
が使えなかったので諦めた。)
Dockerイメージからコンテナを作成する際にホスト側にMySQL用の.cnf
ファイルを用意しファイルを配置したディレクトリをマウントします。
(DockerHubのMySQLイメージのページを確認すると起動オプションでも指定できるようですが私は確認していません。)
DockerのMySQL公式イメージはコンテナ起動時に/etc/mysql/conf.d
配下の.cnf
ファイルを読み込んでくれるようです。
そこでホスト(ローカル)にcustom.cnf
を用意して起動時にマウントします。
.cnf
ファイルの用意
/tmp/dockerdir/custom.cnf
[mysql] default-character-set=utf8 [mysqld] character-set-server=utf8
ディレクトリをマウントしてMySQLコンテナを起動
$ docker run -v /tmp/dockerdir:/etc/mysql/conf.d/ --name twe-todo -e MYSQL_ROOT_PASSWORD=password -d -p 33306:3306 mysql:5.7
マウントする際は-v <ホストパス>:<コンテナパス>
で指定します。
文字コード設定の確認
文字コードが変更されていることが確認できました。
mysql> show variables like "%char%"; +--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+
DB再作成
手順は省きますがスキーマを作成しdotnet ef
コマンドを使用してテーブルを作成します。
動作確認
文字化けせずにツイートできたことが確認できました。
また、データ上も文字化けせずに登録されていることが確認できます。
mysql> select * from Task; +----+-----------------------------+-------+---------------+ | id | task | state | TweetResultid | +----+-----------------------------+-------+---------------+ | 2 | 文字コードとの戦い | 1 | 1 | +----+-----------------------------+-------+---------------+
トラブルシュート
dockerコンテナ起動時のログ確認
custom.cnf
で文字コード設定を追加した後、dockerコンテナがエラーで起動していませんでした。
起動時のログは下記コマンドで確認可能です。
# コンテナID確認 $ docker ps -a # ログ確認 $ docker logs <コンテナID>
課題
業務でもmy.cnf
をいじることはあったんですがすでに設定されている設定値を変更したり手順書があったりで全然身についてませんでした。
正直ググったまま書いてあることを忠実に実行した感じなので文字コードの設定に関して理解できたわけじゃない。 と言うより各項目の公式リファレンスを見つけることができなかった。
雑感
やっと開発環境が整った感じがします...