Docker PR

Dockerで構築したMySQLで日本語の文字化けが起きたときの対処法【MySQL Docker】

Dockerで構築したMySQLで日本語の文字化けが起きたときの対処法【MySQL Docker】
記事内に商品プロモーションを含む場合があります

こんにちは!Webエンジニアに転職するべく、ポートフォリオ作成中のモリヤス(@_moriyas)です。

MySQLで作ったDBとSpring Bootを使ってAPIを作っていたのですが、DBの登録されている日本語の文字列データやJSON形式のレスポンスデータの日本語文字列が文字化けする問題が起きました。

その際に解決するまで少し時間がかかってしまったので、備忘録として残しておきます。

環境・バージョン

  • Docker v24.0.2
  • Docker Compose v2.18.1
  • MySQL v8.0.33

起きた問題

DBの登録されている日本語の文字列データが文字化けしていた。(JSON形式のレスポンスデータの日本語文字列も文字化けしていた)

Terminal
mysql> select * from table_name;

|  1 |  1|  ???? ??      |    
|  2 |  1|  ???? ??      | 
|  3 |  1|  ???            | 
|  4 |  2|  ????          | 
|  5 |  2|  ????          | 
+----+--+------------------+

「MySQL Docker 文字化け」と検索すると出てくるような多くの記事で言及されている「MySQLの文字コード」を確認すると下記のように表示された。

参考記事「【備忘録】Dockerコンテナ内のMySQLが文字化けしたので修正した」

Terminal
mysql> show variables like "%chara%";

+--------------------------+----------------------------+
| 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/ |
+--------------------------+----------------------------+

MySQLの設定ファイルのmy.cnfに下記の設定をしてあげて文字コードの設定を変えるとよさそうだ。

my.cnf
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_bin

[mysql]
default-character-set=utf8mb4

[client]
default-character-set=utf8mb4

では、再度MySQLのdockerコンテナを立ち上げて、文字コードを確認してみる。

Terminal
$ docker-compose down

$ docker-compose up -d

$ docker exec -it container_name bash

bash> mysql -u root -p

mysql> show variables like "%chara%";

+--------------------------+----------------------------+
| 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/ |
+--------------------------+----------------------------+

……

あれれ?

変わってない!!!

色々な記事を見ても、ほぼ上記の対応で文字コードが変わるとのことだったので、困った。

解決できた方法の結論

docker-compose.yamlファイルで設定している、my.cnfファイルのマウント先を修正する!

docker-compose.yaml
    volumes
      - ./sql/my.cnf:/mysql/conf.d/my.cnf  ←こうなっていたのを
      - ./sql/my.cnf:/etc/mysql/conf.d/my.cnf ←これに書き換える

解決できた方法の詳しい解説

そもそもmy.cnfの内容が反映されていないということでmy.cnfの設定をMySQLコンテナに反映させるdocker-compose.yamlファイルが怪しいのではないかと考えた。

調べてると下記の記事を見つけた。

参考記事「Docker で MySQL コンテナを作る方法 – LAZE SOFTWARE」

この記事内に「MySQL の設定ファイルは複数の場所に置くことができますが、デフォルトだと “/etc/my.cnf” ファイルを見に行き、そこから “/etc/mysql/conf.d” ディレクトリの配下を見に行くようです。なので、独自の設定ファイルを置きたい場合は、”/etc/mysql/conf.d” ディレクトリに置くと良いでしょう」という説明があった。

my.cnfファイルをコンテナ内の決まったディレクトリのファイルにマウントしてあげる必要があるのか!!

ということで現在のマウント先を調べてみることに

docker-compose.yaml
version: "3.8"

services:
  mysql:
    image: mysql:8.0.33
    container_name: container_name
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${ROOTPASS}
      MYSQL_PORT: 3306
      MYSQL_DATABASE: ${DATABASE}
      MYSQL_USER: ${USERNAME}
      MYSQL_PASSWORD: ${USERPASS}
    ports:
      - 3306:3306
    volumes
      - ./sql/init:/docker-entrypoint-initdb.d
      - ./sql/my.cnf:/mysql/conf.d/my.cnf  ←ここを修正する

「/mysql/conf.d/my.cnf」となっており、これが悪さをしてそうです!

では、docker-comopse.yamlを修正していきましょう!

docker-compose.yaml
version: "3.8"

services:
  mysql:
    image: mysql:8.0.33
    container_name: container_name
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: ${ROOTPASS}
      MYSQL_PORT: 3306
      MYSQL_DATABASE: ${DATABASE}
      MYSQL_USER: ${USERNAME}
      MYSQL_PASSWORD: ${USERPASS}
    ports:
      - 3306:3306
    volumes
      - ./sql/init:/docker-entrypoint-initdb.d
      - ./sql/my.cnf:/mysql/conf.d/my.cnf  ←これを削除
      - ./sql/my.cnf:/etc/mysql/conf.d/my.cnf ←これに書き換える

再度コンテナを立ち上げて確認する。

Terminal
$ docker-compose down

$ docker-compose up -d

$ docker exec -it container_name bash

bash> mysql -u root -p

mysql> show variables like "%chara%";
+--------------------------+--------------------------------+
| Variable_name            | Value                          |
+--------------------------+--------------------------------+
| character_set_client     | utf8mb4                        |
| character_set_connection | utf8mb4                        |
| character_set_database   | utf8mb4                        |
| character_set_filesystem | binary                         |
| character_set_results    | utf8mb4                        |
| character_set_server     | utf8mb4                        |
| character_set_system     | utf8mb3                        |
| character_sets_dir       | /usr/share/mysql-8.0/charsets/ |
+--------------------------+--------------------------------+

見事に文字コードの設定が反映されていました!٩( ‘ω’ )و

その後、DBの登録されている日本語の文字列データやJSON形式のレスポンスデータの日本語文字列を確認すると、文字化けが直ってました!

めでたしめでたし!

終わりに

docker-compose.yamlをなんとなくで書いていた弊害!!

まぁでも、いきなり全部の書き方を理解するのはきつすぎる話なので、こうやってつまりながら都度覚えていくのが良いかもな!!なんて思った次第です!

はやく転職活動できるように、しっかりポートフォリオ作り上げたいと思います٩( ‘ω’ )و

参考記事

【備忘録】Dockerコンテナ内のMySQLが文字化けしたので修正した

参考記事「Docker で MySQL コンテナを作る方法 – LAZE SOFTWARE」

MySQL 文字コード確認