Dockerfileを修正する硬派な方法5:補足・ハマりポイント6:まとめ関連するこちらの記事もオススメwordpressで画像はどのようにデータベースに記録されているかjavascriptでデバイスの物理画面サイズを推定する方法GitHubでSSHkeyを登録し接続する標準出力と標準エラー出力を闇に葬るまたもや言語設定でのリファラスパム「o-o-8-o-o.com」Docker公式MySQLのDockerfileを頑張って読んで理解しようとしてみた[Dockerfile本体編]PHPで「文字列を区切り文字を指定して分割し配列におさめる」explode関数bashのキーバインドを覚えて快適コマンドライン生活マルチバイト語族をなめてんのかごっつり文字化けするんですよね...。Dockerの公式MySQLはcaracter-set-serverがデフォルトのまんまのlatin1です。そりゃASCII文化圏ならutf8だろうがlatin1だろうが文字化けしないだろうさ...。マルチバイト語族は常に、つ、ね、に、文字化けの恐怖に晒されるのですよ。そこで今回はDockerの公式MySQLでちゃんと日本語を扱えるようにするための方法をまとめてみました。記事ではMySQL5.7(mysql/5.7/Dockerfile)を使っています。設定変更の方法を紹介する前にちょっとした説明です。MySQLで文字化けの原因となるのはcaracter-set-serverがデフォルトのlatin1のままになっている為というのがあります。日本語を扱うにはマルチバイトの文字セットが必要ですが、現状だとutf8、utf8mb4を使うことになるかと思いますたとえば日本語の漢字で「泡」はutf8でE6B3A1というコードになります。3バイトで表現されていることがわかるかと思います。utf8という解釈をするとこのコードは「泡」ということになるのですが、1バイト毎での解釈もできてしまう余地があります。A11バイトの文字が3つとも解釈できるのです。「泡」は「æ3¡」になってしまうのです。こんな風にutf8で書いた文字列がlatin1として解釈される「コードの取り違え」があると以下の様な壮絶な文字化けが発生してしまうのです。3⁄4ã‚Œã‚なにやらこんな文字化け見たことありますよね。ちなみにアルファベット・アラビア数字・一般的な記号部分が文字化けしないのは、それらを定義しているASCIIという文字セットがほとんどの文字セットに含まれているからです。(つまり同じコードを使っているので文字化けしようがない)latin1もASCIIを含んでいるのでアルファベット・アラビア数字・一般的な記号部分は文字化けしません。次は具体的な方法に行きましょう。コンテナを作る時に設定ファイルを変更する方法caracter-set-serverを恒久的に設定するにはmy.cnfを編集する必要があります。この方法は直接手動でmy.cnfを修正する方法です。設定を確認できるので、MySQLコンテナの設定を把握したい場合などにいいかもしれません。my.cnfを得るまずは型になるmy.cnfを手に入れましょう。これはコンテナから引っこ抜くのが早いです。「my.cnfをコピーする用」のコンテナを作ります。cpコマンドでコンテナからmy.cnfをコピーします。my.cnfエディタで開いてみましょう。my.cnfMySQLコンテナに作られたmy.cnfは以下のような記述になっています。/var/log/mysql/error.logがsedでの処理でコメントアウトされています。caracter-set-server書き足しさてutf8をデフォルトにするためにcaracter-set-serverの設定を書き加えます。utf8mb4を書き加えます。以下のようになっていれば大丈夫です。/usr/share/mysqlexplicit_defaults_for_timestamp~~~~~~~~さようならコンテナいま修正したmy.cnfを適用させた新しいコンテナをつくるので、「my.cnfをコピーする用」に作ったコンテナは削除して構いません。例では/hoge/mycnf/)。そのディレクトリをデータボリュームとしてコンテナと共有することでmy.cnfをコンテナの中に入れます。公式MySQLでインストールされているMySQLは/etc/mysql/conf.d/に*.cnf形式のファイルが入っているとその設定を優先するようになっています。ignored./etc/mysql/my.cnfを上書きするのでも問題はないのですが、今回は/etc/mysql/conf.d/につっこんでいくスタイルでいきます。my.cnfという名前じゃなくても大丈夫です。拡張子さえcnfにしていれば管理しやすい様に名前を変えても問題ありません。「使う用のコンテナ」を作る以上のことを踏まえて「使う用のコンテナ」は以下のようにして作ります。mysqlこれで修正したmycnfの設定が生きたコンテナが出来ました。文字化けしていたのが...なんということでしょう...!!わ〜い。Dockerfileを修正する硬派な方法コンテナからmy.cnfをコピーするなど軟弱なことはやっておれん、という硬派な方にはDockerfileの修正がオススメです。GitHubからDockerfileをcloneしましょう。git@github.com:docker-library/mysql.gitDockerfileを開きます。mysql/5.7/Dockerfileいろいろ処理が書かれていますが、34行目あたりに以下のような記述があります。この部分がmy.cnfを修正している箇所になります。/etc/mysql/my.cnfさらに詳しくみると以下の部分が、「[mysqld]の直下にskip-name-resolveおよびskip-host-cacheを挿入する処理」を行っている箇所です。\ここを修正すればcaracter-set-serverを挿入することができるかと思います。以下の様にしてみてください。\さて修正したDockerfileをbuildしましょう。hoge/mysql/5.7/buildしたイメージでコンテナを作ります。utf8mb4が挿入されていますね。buildが失敗するかもしれません。foundこれはdebianリポジトリに指定したバージョンが無いときに起こるエラーのようです。この記事を書いている時ちょうど5.7.12-1debian8がリリースされたようで、5.7.11-1debian8がリポジトリからなくなりました。Dockefileのメンテを待っても良いのですが、直接書き換えても大丈夫かと思います。今回はDockerfileの以下の様に書き換えました。5.7.12-1debian8あとで確認したらGitHubの方もすでに修正されていました。ちなみにこの件に関してはissuesがあります。バージョンを取り違えないように、その都度指定する方法にしているみたいですね。#139もし上記のようなエラーがでたら確認してみてください。mino長年働いていた会社をリストラされてしまったおっさん。なにを思ったか未経験のプログラミングで再起を図ろうとする。プログラミングを勉強していく上で苦しんだこと、ハマったことを中心に記事を書きます。