ローカル環境を汚さずにMySQLの動作検証をサクッとしたかったので、Dockerを使うことにしました。
やりたい検証は単純なものだったので「わざわざDockerfileを準備しなくても、ベースイメージから直接コンテナを起動すればいいか」と思い、以下のコマンドを実行しコンテナを起動→MySQLに接続しました。
$ docker run --name mysql_container -e MYSQL_ALLOW_EMPTY_PASSWORD=true -d mysql:8.0.36
$ docker exec -it mysql_container bash
bash-4.4# mysql
mysql>
ここまでは、何の問題もありませんでしたが、日本語を含んだSELECT文を実行する際に、問題が発生しました。
以下のように「あ」を入力中、確定するためにEnterを押すと「あ」が消えてしまうのです。
mysql> SELECT 'あ
今回は、これを解決するまでの過程を記事にします。
いきなり解決方法
解決さえすれば、それでいいんだという方のためにまずは解決方法から
以下のDockerfileを使えば、MySQLで日本語を入力することができるようになります。
FROM mysql:8.0.36-debian
RUN apt-get update && apt-get install -y locales
RUN sed -i 's/# ja_JP.UTF-8 UTF-8/ja_JP.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
ENV LANG ja_JP.UTF-8
実行コマンド
$ docker build . -t mysql_image
$ docker run --name mysql_container -e MYSQL_ALLOW_EMPTY_PASSWORD=true -d mysql_image
$ docker exec -it mysql_container bash
root@d7a83e3b721c:/$ mysql
mysql> SELECT 'あ' = 'ア' as test;
+------+
| test |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
原因
OSのロケール設定ができていないことが原因でした。
解決するまでの道のり
あれこれ調べてみると、OSのロケール設定についての情報がいくつか見つかったので、これが原因だと仮定して、解決を試みることにしました。
手順は次のとおりです。
- ベースイメージだけのコンテナ(冒頭のコンテナ)を作成し接続する
- コマンドを入力して解決方法を探る
- 実行したコマンドをDockerfileに反映させる
- Dockerfileから作成したイメージで起動したコンテナを使って確認する
ベースイメージだけのコンテナを作成し接続する
冒頭の繰り返しになりますが、以下のとおりです。
$ docker run --name mysql_container -e MYSQL_ALLOW_EMPTY_PASSWORD=true -d mysql:8.0.36
$ docker exec -it mysql_container bash
bash-4.4#
コマンドを入力して解決方法を探る
必要なパッケージのインストール
まずはロケール設定に必要なパッケージをインストールします。
bash-4.4# apt-get update
bash: apt-get: command not found
apt-get
コマンドがないだと…
無印のmysql:8.0.36ではoraclelinuxが使われていることが原因のようです。
yum
なら使えそうですが、今回の目的は「MySQLの動作検証をサクッとしたい」であり、Linuxのディストリビューションにこだわりはありません。
すでにapt-get
を使う前提で調べ始めていたので、ベースイメージをmysql:8.0.36-debian
で進めることにします。
では、気を取り直して
$ docker run --name mysql_container -e MYSQL_ALLOW_EMPTY_PASSWORD=true -d mysql:8.0.36-debian
$ docker exec -it mysql_container bash
root@f73d6f614309:/$ apt-get update
今度は無事、パッケージリストを更新できました。
次はロケール設定を行うためのパッケージ「locales」をインストールしていきます。
root@f73d6f614309:/$ apt-get install -y locales
無事、インストールが完了しました。
日本語を使うための設定
まずはlocale-gen
コマンドで日本語のロケールを生成します。
生成されるロケールは/etc/locale.genで定義されており、今回使用したい日本語はja_JP.UTF-8
です。
実際に/etc/locale.genを確認してみます。
root@f73d6f614309:/$ cat /etc/locale.gen | grep ja_JP.UTF-8
# ja_JP.UTF-8 UTF-8
コメントアウトされた行はlocale-gen
を実行しても、ローケルが生成されません。
最終的にDockerfileに反映させたいので、エディタを起動して手修正するのではなく、コマンドでコメントアウトを外します。
root@f73d6f614309:/$ sed -i 's/# ja_JP.UTF-8 UTF-8/ja_JP.UTF-8 UTF-8/' /etc/locale.gen
root@f73d6f614309:/$ cat /etc/locale.gen | grep ja_JP.UTF-8
ja_JP.UTF-8 UTF-8
これで日本語のロケールを生成する準備はOK。locale-gen
を実行します。
root@f73d6f614309:/$ locale-gen
Generating locales (this might take a while)...
ja_JP.UTF-8... done
Generation complete.
生成したja_JP.UTF-8
を使うようにLANG
に設定します。
root@f73d6f614309:/$ export LANG=ja_JP.UTF-8
再びMySQLに接続して動作確認
日本語設定が完了したので、冒頭と同じように日本語が入力できるか試してみます。
今度は「あ」を入力して、Enterで確定しても「あ」が消えないため最後まで入力できました!
root@f73d6f614309:/$ mysql
mysql> SELECT 'あ' = 'ア' as test;
+------+
| test |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
実行したコマンドをDockerfileに反映させる
これで何をすれば日本語が使えるようになるかわかったので、ここまで実行してきたコマンドをDockerfileに反映させます。(冒頭で示したファイルと同じです。)
FROM mysql:8.0.36-debian
RUN apt-get update && apt-get install -y locales
RUN sed -i 's/# ja_JP.UTF-8 UTF-8/ja_JP.UTF-8 UTF-8/' /etc/locale.gen && locale-gen
ENV LANG ja_JP.UTF-8
Dockerfileから作成したイメージで起動したコンテナを使って確認する
以下のとおり、日本語が使用できています!
$ docker build . -t mysql_image
$ docker run --name mysql_container -e MYSQL_ALLOW_EMPTY_PASSWORD=true -d mysql_image
$ docker exec -it mysql_container bash
root@d7a83e3b721c:/$ mysql
mysql> SELECT 'あ' = 'ア' as test;
+------+
| test |
+------+
| 1 |
+------+
1 row in set (0.00 sec)
まとめ
MySQLに問題がありそうなタイトルを付けていますが、実際にはLinuxのローケル設定の問題でした。(同じような問題にぶつかった人が、この記事に辿り着いてくれればという思いを込めたタイトルです。)
また、今回は情報収集の結果「Linuxのロケール設定が原因である」と仮定して、それを解決するための方法を調査・検証し、目的を果たすことができました。
もしかしたら他にも解決方法があるかもしれませんが、自分なりの仮説を持つことで調査・検証が進めやすくなるということを、あらためて実感しました。