コンテナ:app(PHP), db (MySQL), server(Nginx)の場合です。
目次
なぜこのエラーが出るか
おそらく、dbのコンテナでmy.cnfをvolumeマウントしている。
imageは mysql-server(Oracle)でもmysql(Docker公式)でもよい。
mysqlの方を使うのが標準ではある。
解決方法
別ファイル名にしてマウント
すでにmysqlのdocker公式imageのentrypointがetc/mysqlであり、権限変更する際に、ローカルのmysql/以下をマウントする際に、衝突してしまう。
cnfファイルはconf.dにあれば読み込まれるので、上書きせず、別ファイル名でマウントする。
- docker-compose.yml -
- ./docker/mysql/my.cnf:/etc/mysql/conf.d/custom.cnf
マウントせずコピー
もしくは、Dockerfileでコピーする。マウントすると権限変更が実行されるのでコピーしてから権限を変更する。これはimageによるかもしれない。
- mysql/Dockerfile -
COPY ./docker/mysql/my.cnf /etc/my.cnf
RUN chmod 644 /etc/my.cnf
USER権限を追加
USER: 1000:1000を追加する。権限変更はrootでの実行時にmysqlユーザーに変更するためなので、あらかじめユーザーを追加しておく。
これでもうまく行ったが、あまりいい方法ではない。USERを固定するとentrypointと衝突する可能性がある。
https://belonginc.dev/members/mohiro/posts/upgrade-mysql/
原因
原因は MySQLコンテナの設定ファイルのマウント方法が原因。
**MySQL のDocker公式イメージは、起動時に以下を実行する。
- 設定ディレクトリの初期化
- 所有者変更(chown)
- mysqlユーザーへの切り替え
このとき
/etc/mysql/my.cnf
などを 直接マウント(bind mount)すると chown: changing ownership of …
確認すること
docker-compose.ymlでmy.cnfをvolumeにかかない。
今回の件とは別件だが
ORMを使う時はappコンテナにmysql cliは不要
app コンテナ(PHP)は db コンテナにTCP接続するだけなので、mysql CLIクライアントは不要。
app(PHP) → TCP:3306 → db(MySQL)
php artisan migrate などもPHPのPDOドライバ経由で接続するので、mysql コマンド自体は使わない。
mysql コマンドが必要になるのは db コンテナに直接入って操作するときだが、それは db コンテナ自体に既に入っている。
別コンテナからdbコンテナへmysqlコマンドで接続する
mysql8はデフォルトでsslを使おうとしているが、sslはないので、コマンドでの接続時には
mysql -h db -u user -p --skip-ssl
とする。