MySQL
docker
dockerfile
docker-compose

【Windows】docker-composeを使ってmy.cnfの共有は気を付けよう!(🍣=🍺問題など)

概要

Docker-composeでSinatra + Nginx + MySQL を動かす時のハマりポイント - Qiitaのプログラムをdocker-composeで動かしていた時に🍣=🍺問題やハハ=パパ問題に遭遇しました。
その際、対処のためにmysqlの文字コードの設定を変えたかったのですが、結構ハマったのでメモです。

🍣=🍺問題?ハハ=パパ問題?

以下が参考になります。
MySQL と寿司ビール問題 - かみぽわーる
MySQL で utf8 と utf8mb4 の混在で起きること - @tmtms のメモ

解決策としては文字コードは基本的にutf8mb4を使って、mysqlの設定でcollation-server=utf8mb4_binとすればよさそう。

docker-composeでmysqlの設定を変えるときの注意点

docker-composeにはサービスごとにcommandでコンテナ内でコマンドを実行できます。
しかし原則1コマンドしか実行できないので、複雑な設定を適用したい場合は困ります。

設定を少しいじる場合
version: "3"

services:
・・・
・・・

   db:
     image: mysql:latest
     environment:
       MYSQL_ALLOW_EMPTY_PASSWORD: "true"
       MYSQL_DATABASE: "latestgram"
       MYSQL_USER: "root"
     volumes:
       - ./sql:/docker-entrypoint-initdb.d
     command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
     ports:
       - "3306:3306"

よって、以下のmy.cnfに設定ファイルを書いてしまってマウントする方法が考えられます。

sql/my.cnf
[mysql]
default-character-set=utf8mb4
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_bin
[client]
default-character-set=utf8mb4
上手くいかない例
  db:
    image: mysql:latest
    volumes:
      - ./conf/my.cnf:/etc/mysql/my.cnf

しかしこれではWindows上でVirtualBox経由でdockerを起動させている場合に上手くいきません(Windows勢に優しくない世界・・・)

Windows + docker-compose + mysql で文字化けさせない方法 - Qiita
上記を参考にすると

  • mysql は File の Permission が 777 の .cnf を読まない。
  • Windows からVirtualBox経由でマウントしているディレクトリ/ファイルはすべて 777 になる。
  • /etc/mysql/conf.d で volume 指定したファイルも 777 になる。

という理由のようです。

Docker mysql 設定変更 - LOCAL-C BLOG
ということで上記を参考に、Dockerfileでマウントしてchmodでパーミッションを644にするという方法で対処します。

sql/Dockerfile
FROM mysql:latest

ADD ./my.cnf /etc/mysql/my.cnf

RUN chmod 644 /etc/mysql/my.cnf

これで以下のようにdocker-composeを書き換えれば適用されます

docker-compose.yml
version: "3"

services:
・・・
・・・
  db:
    build: ./sql
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: "true"
      MYSQL_DATABASE: "latestgram"
      MYSQL_USER: "root"
      TZ: "Asia/Tokyo"
    volumes:
      - ./sql:/docker-entrypoint-initdb.d
    ports:
      - "3306:3306"