【Docker・M1 Mac備忘録】rootユーザーでPHPプログラムやphpMyAdminからログインできなかった件 〜参考書通りにdocker-compose.ymlを書いたがMySQLが使えなかった話 その2〜

1.はじめに

今までDockerなんて触ったこともなかった僕が、ちょっとした出来心でDockerを勉強したいなと思った話については下記の記事を読んでいただけると幸いです。

【Docker・M1 Mac備忘録】参考書通りにdocker-compose.ymlを書いたがMySQLが使えなかった話〜その1〜 M1 MacでMySQLコンテナを立ち上げる
1.はじめに いままでPHPの開発ではMAMPを使用していたのですが、Laravelの公式チュートリアルでもDockerを使用していたり、今後のためにちゃんと勉強しておくかと思い、最近学習を始めました。 とりあえず、最低限の知識からと思い、

今回はMySQLでrootユーザーが使えなかった件の原因と解決方法についてまとめていきたいと思います。

2.事象

立ち上げたMySQLに対して、PHPプログラムかやphpMyAdminからrootユーザーでログインできない。

なお、ログインを試みた際のエラーメッセージは下記の画像になります。

この時のdocker-compose.ymlとDockerfileは下記の通りです。

version: '3.8'
volumes:
  mysql_db: {}
services:
  phpmyadmin:
    image: phpmyadmin
    environment:
      PMA_HOST: mysql
    ports:
      - '8002:80'
  mysql:
    platform: linux/amd64
    image: mysql/mysql-server:5.7
    volumes:
      - mysql_db:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: '12345678'
    ports:
      - '3306:3306'
  httpd:
    build: .
    volumes:
      - ./htdocs:/var/www/html
    ports:
      - '8001:80'
FROM php:7.3-apache
RUN docker-php-ext-install pdo_mysql

また、PHPのプログラムファイルは下記のようにデータベースに接続するだけのプログラムと内容になっています。

<?php
    try{
        $db = new PDO('mysql:host=mysql;dbname=mysql','root','12345678');
        $msg = 'Connected To MySQL';
        print $msg;
    }catch(PDOException $e){
        $msg = 'Failed connect to MySql(' . $e->getMessage() . ')';
        print $msg;

    }
?>

3.原因

rootユーザーがローカルからのみログインを許可している状態であったことが原因でした。

4.解決方法

外部からアクセスできるようにするには、コンテナを立ち上げてからコマンドで手動でアクセス権限を変更するか、コンテナ立ち上げ時に自動でコマンドを実行するかの二択になると思います。

手動でコマンドを実行するとなると、破棄後のコンテナ立ち上げの度に行わないといけないので、それでは面倒臭いと思いますので、今回はコンテナ立ち上げ時に自動で行う方法を採用したいと思います。

今回は下記の二つのことを行い、コンテナ立ち上げ時にrootユーザーの設定を自動で行うようにします。

・docker-compose.ymlの変更

docker-compose.ymlを下記のように書き換えます。

version: '3.8'
volumes:
  mysql_db: {}
services:
  phpmyadmin:
    image: phpmyadmin
    environment:
      PMA_HOST: mysql
    ports:
      - '8002:80'
  mysql:
    platform: linux/arm64/v8
    image: mysql/mysql-server:8.0
    volumes:
      - mysql_db:/var/lib/mysql
      - ./initdb.d:/docker-entrypoint-initdb.d
    environment:
      MYSQL_ROOT_PASSWORD: '12345678'
      # MYSQL_USER: 'user'
      # MYSQL_PASSWORD: 'pass'
    ports:
      - '3306:3306'
  httpd:
    build: .
    volumes:
      - ./htdocs:/var/www/html
    ports:
      - '8001:80'

「./initdb.d:/docker-entrypoint-initdb.d」を追加して、docker-compose.ymlと同じパスにある「initdb.d」内にある「.sql」「.sh」「.sql.gz」のファイルを実行してくれるらしいです。

・initdb.dフォルダの作成

docker-compose.ymlと同じパスにディレクトリ「initdb.d」を作成します。

・SQLファイルの作成

SQLファイルを作成し下記の内容を記載します。

RENAME USER 'root'@'localhost' TO 'root'@'%';

これで、コンテナを立ち上げるたびに、

5.調査経緯

役に立つか分かりませんが、どのような経緯で原因と解決方法に行き着いたかをまとめておきます。

まず、大体docker内部のネットワークの問題か、ユーザー設定の問題かどちらかに原因があると仮定しました。

そこで、一旦rootユーザーでログインすることを諦めて、コンテナ立ち上げ時に別のユーザーを作成して、ログインできるかを確認してみました。

その時のdocker-compose.ymlが下記の通りです。

version: '3.8'
volumes:
  mysql_db: {}
services:
  phpmyadmin:
    image: phpmyadmin
    environment:
      PMA_HOST: mysql
    ports:
      - '8002:80'
  mysql:
    platform: linux/amd64
    image: mysql/mysql-server:5.7
    volumes:
      - mysql_db:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: '12345678'
      MYSQL_USER: 'user'
      MYSQL_PASSWORD: 'pass'
    ports:
      - '3306:3306'
  httpd:
    build: .
    volumes:
      - ./htdocs:/var/www/html
    ports:
      - '8001:80'

これでコンテナを立ち上げたところ、phpMyAdminからでもPHPプログラムからでも、ログインすることができました。

ここで普通に作成したユーザーを使用して開発を進めてもいいんでしょうけど、今後のためにモヤモヤするのはよくないと思い、原因を探ります。まあ、新規で作成したユーザーは権限が全く付与されていないため、あまり使い物にならないので、そこら辺を開発の際どうすればいいのかというところも含めて調べてみたというところもあります。

これで一つ目のDocker内部のネットワークの問題ではないことが分かりましたので、おそらく権限か、そもそもパスワードの変更ができていないなどユーザー設定の問題であることが予想するところまでできました。

なので、立ち上げているDocker内のMySQLにコマンドで操作してrootのユーザー設定についてみてみました。

まずは、下記のコマンドでMySQLを立ち上げているのコンテナの内部に入り、コマンドで操作できるようにします。

$ docker compose exec mysql bash

続いて、コンテナの中でMySQLにログインします。

$ mysql -u root -p

これでログインすることができたので、docker-compose.ymlでのパスワード設定がミスっているという可能性が消えました。

続いて権限系の問題を調査してみます。MySQLにログインした状態で下記SQLを実行します。

SELECT host, user FROM mysql.user;

下記の結果を見てみたところ、コンテナ立ち上げ時に作成したユーザーは外部からアクセスできますが、rootユーザーは、localhostからしかアクセスできないようです。おそらく、これが原因なのではないかと考えられます。

正直、コンテナの概念をちゃんと理解したとは言えないのでこの場合のローカルってどこのことを指すんだろうという感じですが、とりあえず調査を進めます。

とりあえず、このrootユーザーの「localhost」を「%」に書き換えていきます。

MySQLにログインした状態で下記のSQL文を実行します。

RENAME USER 'root'@'localhost' TO 'root'@'%';

これでPHPやphpMyAdminからログインできるかを試してみます。

ログインできたので、これでrootユーザーでログインできない問題は解決です。

あとは、いちいちこの作業をコマンドを使用してするのも面倒臭いので、コンテナ立ち上げ時に自動で実行する方法を調査して完了となります。

6.末筆

なんやかんや普段データベース操作はGUIツールなんかを使っているので、ユーザー設定を調べるだけとはいえ、コマンドでデータベースを触るのは新鮮でした。多分、研修の時以来かな。

参考書通りにやっても動かないというのは、少し大変な反面、知識や経験に繋がるんだなと思いました。

もう少しDockerを使い慣れていきたいと思います。

〜参考サイト〜

Docker MySQLコンテナ起動時に初期データを投入する - Qiita
DockerのMySQLイメージは、「/docker-entrypoint-initdb.d」にマウントしたディレクトリに「.sql」「.sh」「.sql.gz」という拡張子でファイルを配置しておく…
MySQL ユーザ名&ホストの変更 - Qiita
MySQL ユーザ名&ホストの変更概要MySQLにおけるユーザ名&ホストの変更について説明します。手順構文RENAME USER 'ユーザー名'@'ホスト名' to '新ユーザー名'@'新…
MySQL | 外部ホストから接続する方法、接続中ユーザの権限情報の確認方法 - わくわくBank
外部のホストからアクセスできるDBユーザーの作成方法について解説します。開発環境などで、外部からMySQLにアクセスしたいときに活用できます。
タイトルとURLをコピーしました