3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Docker 環境の MySQL で日本語が入力できない時

Last updated at Posted at 2025-11-24

はじめに

Docker 環境で MySQL を使う時に日本語がうまく入力できないことがあります。

原因は

  • OS の locale の設定がうまくいっていない
  • MySQL の character set の設定が正しくない

がほとんどだと思いますが、
今回は前者の OS の locale 設定が原因だったケースについてまとめます。

なので、「Docker 環境で」と書きましたが Docker 環境に限った話ではないです。

開発環境で MySQL を使うときは、たいていコンテナを立ち上げて使うと思いますが、
Docker 公式の MySQL のイメージMySQL 公式のイメージも日本語入力用の locale が入っていないため、デフォルトだと日本語を入力することができない状態です。

locale 設定の不備で日本語入力ができない理由

「OS の locale 設定がうまくいっていないため、日本語が入力できない」ではあるのですが、
厳密には「OS の locale 設定がうまくいっていないため、mysql-client が内部で使っている readline が日本語を読み込めていない」です。

mysql-client では、以下の箇所で readline の初期化をしているのですが、
その際に OS の locale を読むようになっています。

setlocale(LC_ALL, ""); が該当箇所で、
これにより OS の locale 関係の環境変数が読まれるようになっています。

If locale is an empty string, "", each part of the locale that should be modified is set according to the environment variables. The details are implementation-dependent. For glibc, first (regardless of category), the environment variable LC_ALL is inspected, next the environment variable with the same name as the category (see the table above), and finally the environment variable LANG. The first existing environment variable is used. If its value is not a valid locale specification, the locale is unchanged, and setlocale() returns NULL.

実際に、以下のような readline を使った簡易的なプログラムを環境変数を変えて実行すると、確認することができます。

#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <stdlib.h>
#include <locale.h>

int main() {
    setlocale(LC_ALL, "");
    
    char *line;
    while ((line = readline("> ")) != NULL) {
        printf("you typed: %s\n", line);
        free(line);
    }
    return 0;
}
$ gcc main.c -lreadline
  • 日本語入力ができない
$ LC_ALL=C ./a.out
  • 日本語入力できる
$ LC_ALL=ja_JP.utf8 ./a.out

locale の設定をする

ということで原因がわかったので、日本語入力ができるように locale の設定をしていきます。
特にバージョンにこだわりはありませんが、今回は

で確認します。

locale の確認をする

mysql:8.4

$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=password -d mysql:8.4
$ docker exec -it mysql bash
$ locale
LANG=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=

$ locale -a
C
C.utf8
POSIX

mysql:8.0.44-bookworm

$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=password -d mysql:8.0.44-bookworm
$ docker exec -it mysql bash
$ locale
LANG=
LANGUAGE=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=

$ locale -a
C
C.utf8
POSIX

日本語を入力したい場合、locale を ja_JP.utf8 に設定する必要がありますが、どちらも設定されていないことがわかります。

ja_JP.utf8 のセットアップ

locale -a の出力を確認したところ、ja_JP.utf8 が含まれていなかったので該当のパッケージをダウンロードしてビルドする必要があります。

mysql:8.4

mysql:8.4 では パッケージマネージャとして microdnf が使われています。
locale のソースファイルを管理しているパッケージは glibc-locale-source なので、それをインストールします。

$ microdnf update && microdnf install -y glibc-locale-source

/usr/share/i18n/ 配下を確認すると、locale のソースファイルが色々落ちてきていることを確認することができます。

これらのソースファイルを元にビルドします。
localedef が最初から入っているので、そちらを使ってビルドすることができます。

以下の例だと、

/usr/share/i18n/locales/ja_JP をインプットに、/usr/share/i18n/charmaps/UTF-8.gz を charmap のファイルとしてビルドした結果を ja_JP.UTF-8 として吐き出しています。

$ localedef -i ja_JP -f UTF-8 ja_JP.UTF-8

吐き出した ja_JP.UTF-8/usr/lib/locale/locale-archive に追加されていて、localedef --list-archive で確認することができます。

$ localedef --list-archive
ja_JP.utf8

$ locale -a
C
C.utf8
POSIX
ja_JP.utf8

これで locale にも設定できるようになったので、環境変数に設定すれば日本語入力ができるようになります。
先ほどの setlocale の箇所で、

For glibc, first (regardless of category), the environment variable LC_ALL is inspected, next the environment variable with the same name as the category (see the table above), and finally the environment variable LANG.

とあったので、特に詳細な設定が必要ない場合は、LC_ALLのみに設定しておけばいいはずです。

$ export LC_ALL=ja_JP.utf8

mysql:8.0.44-bookworm

mysql:8.0.44-bookworm は debian 系なのでパッケージマネージャは apt で、
locale のソースファイルを管理しているパッケージは locales なので、それをインストールします。

$ apt update && apt install -y locales

同様に /usr/share/i18n/ 配下にいっぱい降ってきます。
debian 系なので、内部的に localedef を使っている locale-gen を使ってビルドすることができます。

/etc/locale.gen でコメントアウトされている対象の locale をアンコメントして locale-gen を実行するだけです。
エディタを開いてアンコメントすればいいですが、sed を使ってカッコよくやるとこんな感じです。

$ sed -i -E 's/# (ja_JP.UTF-8)/\1/' /etc/locale.gen
$ locale-gen
$ locale -a
C
C.utf8
POSIX
ja_JP.utf8
$ export LC_ALL=ja_JP.utf8

Dockerfile

これらの手続きを毎回実行するのは容量が悪いので、Dockerfile を書いてカスタムイメージ化しておきます。

mysql:8.4

FROM mysql:8.4

RUN microdnf update && \
    microdnf install -y glibc-locale-source && \
    localedef -i ja_JP -f UTF-8 ja_JP.UTF-8
    # 結構サイズが大きくなったので、microdnf clean all を入れると良さそう

ENV LC_ALL=ja_JP.utf8

mysql:8.0.44-bookworm

FROM mysql:8.0.44-bookworm

RUN apt update && \
    apt install -y locales && \
    sed -i -E 's/# (ja_JP.UTF-8)/\1/' /etc/locale.gen && \
    locale-gen

ENV LC_ALL=ja_JP.utf8
3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?