概要
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(公式)
参考サイト様
- http://d.hatena.ne.jp/kt_hiro/20110907/1315396920 🔗
- https://dev.mysql.com/doc/refman/5.7/en/charset-applications.html 🔗
- https://dev.mysql.com/doc/refman/5.7/en/charset-connection.html 🔗
- https://dev.mysql.com/doc/refman/5.7/en/server-options.html 🔗
- https://qiita.com/tily/items/adb433505da6c7812725 🔗
- https://qiita.com/yukiyoshimura/items/d44a98021608c8f8a52a 🔗
- https://hub.docker.com/_/mysql 🔗
- http://time-complexity.blogspot.com/2013/10/mysqlmycnf.html 🔗
事象
下記のようなFormにツイート内容を記入しツイートします。
その過程でツイートの記録を残すためDB上にデータを残しています。
しかし、DBに登録されたデータが文字化けしてしまうと言う事象です。
下記のようなFormからツイート内容を登録します。
上記の画面から登録/更新を行ったデータが下記です。
(まあ、登録時点で文字化けしてるので更新もクソもないですが…)
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からデータを取得すると文字化けしたデータしか取得できないので下記のような文字化けしたツイートになってしまいます。
https://twitter.com/Lychee_jam/status/1101743899746304000 🔗
原因
MySQLの文字コード設定がUTF-8
となっていないため。
DcokerのMySQL公式イメージを使用しているのですが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について
ラテン文字用の文字コードらしい。詳しくは調べてない。
https://ja.wikipedia.org/wiki/ISO/IEC_8859-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
をいじることはあったんですがすでに設定されている設定値を変更したり手順書があったりで全然身についてませんでした。
正直ググったまま書いてあることを忠実に実行した感じなので文字コードの設定に関して理解できたわけじゃない。 と言うより各項目の公式リファレンスを見つけることができなかった。
雑感
やっと開発環境が整った感じがします…