概要
docker-compose.yamlでphpmyadminを使っている方なら見たことあると思うのですが、PMA_PASSWORDをご存知でしょうか。
普段使ってなかったのですが、その存在を知ったので、今回これを使って実装しました。
「これってphpmyadmin用のもの?」「Mysqlサーバ側と違うユーザーとパスでもいいの?」という疑問があったので調べてみました。
前提
以下の簡易的なdocker-compose.yamlを使用する前提です。
version: '3.8'
services:
mysql:
image: mysql:latest
restart: always
environment:
MYSQL_ROOT_PASSWORD: rootpassword
MYSQL_DATABASE: exampledb
ports:
- "3306:3306"
volumes:
- db_data:/var/lib/mysql
phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
restart: always
environment:
PMA_HOST: mysql
PMA_USER: root
PMA_PASSWORD: rootpassword
ports:
- "8080:80"
depends_on:
- mysql
volumes:
db_data:
上記の状態でdocker-compose upを行えば、phpMyadminへ正常にアクセスできます。
以下で登場するPMA_PASSWORDやMYSQL_ROOT_PASSWORDは上記のことを指します。
PMA_PASSWORDはphpMyadmin専用のパスワード?
答えはNOです。
私は最初phpMyadmin用に新規にユーザーとパスワードを設定するための項目と思ったのですが、違いました。
上記の例で言えば、
・PMA_USER -> root
・PMA_PASSWORD -> MYSQL_ROOT_PASSWORDで指定したrootpassword
とすることで、MySQLサーバーに接続することができます。
上記でPMA_PASSWORDをMYSQL_ROOT_PASSWORDと別のパスワードを設定すると以下の画面でエラーになります(ただし必ずしも一致しなくて良いケースがあるので後述)。
エラー
MySQL のメッセージ: 接続できません。設定が無効です。
mysqli::real_connect(): (HY000/2002): Connection refused
MySQL サーバに接続しようとしましたが拒否されました。config.inc.php のホスト、ユーザ名、パスワードが MySQL サーバの管理者から与えられた情報と一致するか確認してください。
同様に、この時点でPMA_USERをroot以外にしても同じエラーでphpMyadminに入れません。
ちなみに 少し経ってから再試行すると以下のエラーに切り替わります。
以下の部分のエラーメッセージが微妙に変わるようですが、ログイン画面すら出てこないのは同様です。
mysqli::real_connect(): (HY000/1045): Access denied for user 'root'@'192.168.144.3' (using password: YES)
絶対にPMA_PASSWORDとMYSQL_ROOT_PASSWORDは一致しなきゃだめ?
実はこれはNOです。
上述のケースは、まだデフォルトrootユーザー以外にユーザーがない場合。
root以外で定義したいんだ!って場合は、
以下の操作でまずALL権限のあるMySQLユーザーが作成できます。
$ docker exec -it mysql_container_name bash
$ mysql -uroot -prootpassword
$ CREATE USER 'foofoo'@'%' IDENTIFIED BY 'hogehoge';
$ GRANT ALL PRIVILEGES ON *.* TO 'foofoo'@'%';
$ FLUSH PRIVILEGES;
上記を実施すれば、以下のように定義してもルートユーザーとして使えます。
そしてこの場合は、MYSQL_ROOT_PASSWORDと一致していなくともOKです。
environment:
PMA_HOST: mysql
PMA_USER: foofoo
PMA_PASSWORD: hogehoge
何のためにPMA_USERとPMA_PASSWORDを定義するの?
ここまで来たら、次の質問はこれになると思います。
「PMA_USERとPMA_PASSWORDって不要なんじゃ?」
現状、わざわざdocker-compose.yamlでPMA_USERとPMA_PASSWORDを定義しなくとも、mysqlの方で定義すればいいからです。新規ユーザを作成したとしても、わざわざPMA_USERとPMA_PASSWORDで定義する意味はあるのでしょうか?
PMA_USERとPMA_PASSWORDの用途は、ズバリ「ログイン画面(認証ページ)のスキップ」です。
これらを定義していない場合は、毎回ログイン画面が出てきて、ユーザーとパスワードを入力する必要があります。
これらを定義することで、ブラウザからPHPMyAdminへのアクセス時に認証画面をスキップし、直接PHPMyAdminのインターフェースを表示するための暗号鍵のようなイメージとして使用されているのです。
ただし、誰でもログイン画面を通さずにデータベースにアクセスできる可能性がある、という状態はセキュリティリスク的にあまりよろしくないでしょう。常にユーザー認証を要求する方が安全と言えます。
スキップができるワケは...config.inc.phpにあった
上述のエラーメッセージにも記載のあったconfig.inc.phpとは何なのか?
実は関係おおあり、というかこれを理解すると一番早かったです。
config.inc.phpはphpMyAdminコンテナ内の特定の場所に配置されている設定ファイルのようなもので、データベース接続情報、認証情報、テーマ、セキュリティ設定などのカスタマイズができます。使用しているイメージによって違うかもしれませんが、私の場合は/etc/phpmyadmin/にありました。
config 認証モードについて、公式ドキュメントには以下のように説明がありました。
クッキー認証や HTTP 認証とは異なり、最初に phpMyAdmin サイトを読み込んだときに、ユーザがログインする必要がありません。これは仕様によるものですが、インストール先へのアクセスをどのユーザにも許可しているということです。
つまり、config 認証モードを使用する場合は、config.inc.phpファイルに PMA_USER と PMA_PASSWORD を設定することで、直接的な認証情報を定義することができるのですが、docker-compose.yamlを利用してPMA_PASSWORDを定義してあげることもできる、ということです。この場合、環境変数として渡される認証情報はconfig.inc.phpには直接書き込まれません。
確かにconfig.inc.phpを見てみると以下のように記述があります。
これらの環境変数を受け取っているのですね。
# cat config.inc.php
<?php
require('/etc/phpmyadmin/config.secret.inc.php');
/* Ensure we got the environment */
$vars = array(
'PMA_ARBITRARY',
'PMA_HOST',
'PMA_HOSTS',
'PMA_VERBOSE',
'PMA_VERBOSES',
'PMA_PORT',
'PMA_PORTS',
'PMA_SOCKET',
'PMA_SOCKETS',
'PMA_USER',
'PMA_PASSWORD',
'PMA_ABSOLUTE_URI',
'PMA_CONTROLHOST',
'PMA_CONTROLPORT',
'PMA_PMADB',
'PMA_CONTROLUSER',
'PMA_CONTROLPASS',
'PMA_QUERYHISTORYDB',
'PMA_QUERYHISTORYMAX',
'MAX_EXECUTION_TIME',
'MEMORY_LIMIT'
);
### 略
ということで、PMA_USERとPMA_PASSWORDについて理解ができました。
ただし、セキュリティリスクもあると思うのでこれを利用する時はケースバイケースでご判断ください。

