2月も中旬に差し掛かろうとするこのタイミングで今年最初のブログエントリです。サボり癖を付けないようにしないと。。
久しぶりに phpMyAdmin を使ってみました。MySQL を使っている環境で開発していると、この手の GUI クライアントアプリが欲しくなる機会は多いはずです。アプリ開発でなくても WordPress のような CMS を使っている場合でも、こういった DB に直接アクセスできるツールがあるとちょっとしたデータ変更などにも便利ですよね:

私自身は 10 年以上前に WordPress のカスタマイズをする機会が多かったこともあり、phpMyAdmin のヘビーユーザーでした。当時はまだ「コンテナ」の知識も乏しく、物理/仮想サーバーに直接 PHP や httpd 、そして phpMyAdmin をインストールして使ってました。今回はイメージの便利さを覚えたこともあり、モジュールを直接インストールするのではなく、DockerHub で見つけた公式 phpMyAdmin イメージで挑戦してみました(ついでに MySQL も DockerHub の公式イメージを使い、docker compose を使って構築してみました)。
【ただ普通に使う】
ただ普通に DockerHub の公式イメージを使って MySQL と phpMyAdmin を起動するならこのような docker-compose.yaml を用意するだけです:
上の例では MySQL の root パスワードを root_passw0rd、作成する DB 名は mydb 、アクセスするユーザーは myuser で、そのパスワードは mypass としています(同じユーザーとパスワードで phpMyAdmin からも接続しています)。なので phpMyAdmin で実行できる内容はこのユーザーに与えられた権限次第、ということになります。MySQL は ID とパスワードだけで接続できるよう、MySQL 5.7 を指定して利用します。
また docker compose 実行時のディレクトリに mysql/ というフォルダを作って、MySQL からボリュームマウントしています(MySQL コンテナを再起動してもデータが残るようにしています)。
また phpMyAdmin は 3001 番ポートから接続できるようポートフォワードしました。
この docker-compose.yaml をカレントディレクトリに用意し、mysql/ ディレクトリも作った上で以下のコマンドを実行すると MySQL と phpMyAdmin がコンテナとして起動し、3001 番ポートを指定してブラウザでアクセスすると phpMyAdmin の GUI にアクセスできます:

ここまではさほど難しくありません。
【何が問題か?】
さて、上記までは特別な要素はなくて、一般的な docker-compose と MySQL, phpMyAdmin の知識だけで実現できる内容でした。ところがこのままでは都合悪いケースが結構あります。
なんといっても、URL だけで phpMyAdmin が利用できるということは「認証なしに(データベースのユーザーIDやパスワードを知らなくても)データの内容にアクセスできてしまう」ことになります。例えば MySQL 側であるデータベースに対する参照(SELECT)権限だけを持ったユーザーを作り、そのユーザー ID を docker-compose.yaml 内に記載すれば、phpMyAdmin はそのユーザー権限で使うことになるため、参照しかできない(データの作成や更新、削除はできない)という制約をかけることはできます。ただそれでも、パスワードに相当するセキュリティ要素無しにデータの内容が見れてしまうのは考え物です。
そういった場合の設定として、多くのケースでは phpMyAdmin を開く前に認証を求めるような設定を追加します。代表的な1つとして、ベーシック認証と呼ばれる ID とパスワードの組み合わせを追加するケースも珍しくありません。
ところが phpMyAdmin でベーシック認証を加えるには phpMyAdmin 側というよりも HTTP サーバー側にそのための設定が必要です。物理/仮想サーバーを使って MySQL や phpMyAdmin を用意した場合は同時になんらかの HTTP サーバーもインストールしているはずなので、その中にベーシック認証を使うための設定をすればいいのですが、今回のように phpMyAdmin のコンテナイメージを使っていると、ある程度コンテナの中身も理解していないと、そのためのカスタマイズが困難です。
以下はそのための、つまり phpMyAdmin の公式コンテナイメージを使って HTTP サーバー部分にベーシック認証を追加するための設定方法です。
【phpMyAdmin にベーシック認証をかける】
上述のように phpMyAdmin 公式コンテナでベーシック認証を有効にするには、コンテナイメージ内の HTTP サーバー部分でベーシック認証を有効にする必要があります。具体的には docker-compose.yaml 内で phpMyAdmin を利用する際の HTTP サーバーにベーシック認証を追加するようにイメージをビルドし直してからデプロイするようにカスタマイズします。
そのための手順を以下で紹介します。まず docker-compose.yaml と同じディレクトリにあらかじめ以下3つのファイルを用意しておきます:
・.htpasswd
・.htaccess
・Dockerfile.phpmyadmin
".htpasswd" ファイルはベーシック認証のユーザー ID とパスワードの組み合わせを定義するファイルです。具体的には Linux のターミナルで docker-compose.yaml と同じディレクトリに移動し、以下のコマンドを実行して作成します(実行するとパスワードの入力を求められるので、確認含めて2回パスワードを入力します):
仮にユーザー ID を "admin"、パスワードを "P@ssw0rd" とすると、以下のような内容の .htpasswd ファイルが作成されます(ユーザー ID である admin はそのまま表示されていますが、パスワード部分はエンコードされたものになります):
もう1つのファイル .htaccess は以下の内容で用意します:
"/var/www/html/.htpasswd" ファイルを参照してベーシック認証を実施し、その中に書かれたユーザーID/パスワードと一致しないと認証エラーになる、という内容です。
最後のファイル Dockerfile.phpmyadmin には phpMyAdmin コンテナのビルド内容を記述します。具体的には以下の内容そのままで用意します:
Dockerfile を書いたことがあると内容の意味も理解できると思います。これは「phpMyAdmin (公式コンテナイメージ)をベースに、(上で用意した).htaccess ファイルをコンテナの /var/www/html/.htaccess に、.htpasswd ファイルをコンテナの /var/www/html/.htpasswd ファイルにそれぞれコピーする」という内容が記述されています。
最後に docker-compose.yaml ファイルを一部書き換えて上記のビルドが実行されるようにします:
docker-compose.yaml ファイルに上記赤字部分を追加します。ここでは「Dockerfile.phpmyadmin を使ってコンテナをビルドする」よう指示されています。
ここまでの変更を行って、再度 "docker compose up -d" を実行すると、今度は phpmyadmin コンテナをデプロイする前に上述のビルドが実施され、HTTP サーバーにベーシック認証が追加された状態でデプロイされます。
ここまでの手順が正しく実行されていれば、次に 3001 番ポートを指定してブラウザでアクセスすると、ベーシック認証が求められ、正しいユーザーIDとパスワード(上記例の場合は admin と P@ssw0rd)を入力しないと phpMyAdmin GUI は表示されません:

最低限、このようなベーシック認証で守られていれば URL が分かってもデータの内容にはアクセスできなくなります。MySQL データを GUI で見ることができる phpMyAdmin は便利ですが、インターネットアクセスを許可する場合は最低限このような方法でデータを守る必要があります。最近はコンテナ環境を使うケースも増えていると思うので、そんな人の参考になれば。
久しぶりに phpMyAdmin を使ってみました。MySQL を使っている環境で開発していると、この手の GUI クライアントアプリが欲しくなる機会は多いはずです。アプリ開発でなくても WordPress のような CMS を使っている場合でも、こういった DB に直接アクセスできるツールがあるとちょっとしたデータ変更などにも便利ですよね:

私自身は 10 年以上前に WordPress のカスタマイズをする機会が多かったこともあり、phpMyAdmin のヘビーユーザーでした。当時はまだ「コンテナ」の知識も乏しく、物理/仮想サーバーに直接 PHP や httpd 、そして phpMyAdmin をインストールして使ってました。今回はイメージの便利さを覚えたこともあり、モジュールを直接インストールするのではなく、DockerHub で見つけた公式 phpMyAdmin イメージで挑戦してみました(ついでに MySQL も DockerHub の公式イメージを使い、docker compose を使って構築してみました)。
【ただ普通に使う】
ただ普通に DockerHub の公式イメージを使って MySQL と phpMyAdmin を起動するならこのような docker-compose.yaml を用意するだけです:
version: '3'
services:
db:
image: mysql:5.7
volumes:
- ./mysql:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: root_passw0rd
MYSQL_DATABASE: mydb
MYSQL_USER: myuser
MYSQL_PASSWORD: mypass
phpmyadmin:
depends_on:
- db
image: phpmyadmin
ports:
- "3001:80"
restart: always
environment:
- PMA_ARBITARY=1
- PMA_HOSTS=mydb
- PMA_USER=myuser
- PMA_PASSWORD=mypass
上の例では MySQL の root パスワードを root_passw0rd、作成する DB 名は mydb 、アクセスするユーザーは myuser で、そのパスワードは mypass としています(同じユーザーとパスワードで phpMyAdmin からも接続しています)。なので phpMyAdmin で実行できる内容はこのユーザーに与えられた権限次第、ということになります。MySQL は ID とパスワードだけで接続できるよう、MySQL 5.7 を指定して利用します。
また docker compose 実行時のディレクトリに mysql/ というフォルダを作って、MySQL からボリュームマウントしています(MySQL コンテナを再起動してもデータが残るようにしています)。
また phpMyAdmin は 3001 番ポートから接続できるようポートフォワードしました。
この docker-compose.yaml をカレントディレクトリに用意し、mysql/ ディレクトリも作った上で以下のコマンドを実行すると MySQL と phpMyAdmin がコンテナとして起動し、3001 番ポートを指定してブラウザでアクセスすると phpMyAdmin の GUI にアクセスできます:
$ docker compose up -d

ここまではさほど難しくありません。
【何が問題か?】
さて、上記までは特別な要素はなくて、一般的な docker-compose と MySQL, phpMyAdmin の知識だけで実現できる内容でした。ところがこのままでは都合悪いケースが結構あります。
なんといっても、URL だけで phpMyAdmin が利用できるということは「認証なしに(データベースのユーザーIDやパスワードを知らなくても)データの内容にアクセスできてしまう」ことになります。例えば MySQL 側であるデータベースに対する参照(SELECT)権限だけを持ったユーザーを作り、そのユーザー ID を docker-compose.yaml 内に記載すれば、phpMyAdmin はそのユーザー権限で使うことになるため、参照しかできない(データの作成や更新、削除はできない)という制約をかけることはできます。ただそれでも、パスワードに相当するセキュリティ要素無しにデータの内容が見れてしまうのは考え物です。
そういった場合の設定として、多くのケースでは phpMyAdmin を開く前に認証を求めるような設定を追加します。代表的な1つとして、ベーシック認証と呼ばれる ID とパスワードの組み合わせを追加するケースも珍しくありません。
ところが phpMyAdmin でベーシック認証を加えるには phpMyAdmin 側というよりも HTTP サーバー側にそのための設定が必要です。物理/仮想サーバーを使って MySQL や phpMyAdmin を用意した場合は同時になんらかの HTTP サーバーもインストールしているはずなので、その中にベーシック認証を使うための設定をすればいいのですが、今回のように phpMyAdmin のコンテナイメージを使っていると、ある程度コンテナの中身も理解していないと、そのためのカスタマイズが困難です。
以下はそのための、つまり phpMyAdmin の公式コンテナイメージを使って HTTP サーバー部分にベーシック認証を追加するための設定方法です。
【phpMyAdmin にベーシック認証をかける】
上述のように phpMyAdmin 公式コンテナでベーシック認証を有効にするには、コンテナイメージ内の HTTP サーバー部分でベーシック認証を有効にする必要があります。具体的には docker-compose.yaml 内で phpMyAdmin を利用する際の HTTP サーバーにベーシック認証を追加するようにイメージをビルドし直してからデプロイするようにカスタマイズします。
そのための手順を以下で紹介します。まず docker-compose.yaml と同じディレクトリにあらかじめ以下3つのファイルを用意しておきます:
・.htpasswd
・.htaccess
・Dockerfile.phpmyadmin
".htpasswd" ファイルはベーシック認証のユーザー ID とパスワードの組み合わせを定義するファイルです。具体的には Linux のターミナルで docker-compose.yaml と同じディレクトリに移動し、以下のコマンドを実行して作成します(実行するとパスワードの入力を求められるので、確認含めて2回パスワードを入力します):
$ htpasswd -c .htpasswd (ユーザーID)
仮にユーザー ID を "admin"、パスワードを "P@ssw0rd" とすると、以下のような内容の .htpasswd ファイルが作成されます(ユーザー ID である admin はそのまま表示されていますが、パスワード部分はエンコードされたものになります):
admin:$apr1$OaTHdA4B$vGmbnAxkB5b./q5zXPJHN.
もう1つのファイル .htaccess は以下の内容で用意します:
AuthType Basic AuthName "Please enter your password" AuthUserFile /var/www/html/.htpasswd Require valid-user
"/var/www/html/.htpasswd" ファイルを参照してベーシック認証を実施し、その中に書かれたユーザーID/パスワードと一致しないと認証エラーになる、という内容です。
最後のファイル Dockerfile.phpmyadmin には phpMyAdmin コンテナのビルド内容を記述します。具体的には以下の内容そのままで用意します:
FROM phpmyadmin COPY ./.htaccess /var/www/html/.htaccess COPY ./.htpasswd /var/www/html/.htpasswd
Dockerfile を書いたことがあると内容の意味も理解できると思います。これは「phpMyAdmin (公式コンテナイメージ)をベースに、(上で用意した).htaccess ファイルをコンテナの /var/www/html/.htaccess に、.htpasswd ファイルをコンテナの /var/www/html/.htpasswd ファイルにそれぞれコピーする」という内容が記述されています。
最後に docker-compose.yaml ファイルを一部書き換えて上記のビルドが実行されるようにします:
version: '3'
services:
db:
image: mysql:5.7
volumes:
- ./mysql:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: root_passw0rd
MYSQL_DATABASE: mydb
MYSQL_USER: myuser
MYSQL_PASSWORD: mypass
phpmyadmin:
depends_on:
- db
build:
context: ./
dockerfile: Dockerfile.phpmyadmin
image: phpmyadmin
ports:
- "3001:80"
restart: always
environment:
- PMA_ARBITARY=1
- PMA_HOSTS=mydb
- PMA_USER=myuser
- PMA_PASSWORD=mypass
docker-compose.yaml ファイルに上記赤字部分を追加します。ここでは「Dockerfile.phpmyadmin を使ってコンテナをビルドする」よう指示されています。
ここまでの変更を行って、再度 "docker compose up -d" を実行すると、今度は phpmyadmin コンテナをデプロイする前に上述のビルドが実施され、HTTP サーバーにベーシック認証が追加された状態でデプロイされます。
ここまでの手順が正しく実行されていれば、次に 3001 番ポートを指定してブラウザでアクセスすると、ベーシック認証が求められ、正しいユーザーIDとパスワード(上記例の場合は admin と P@ssw0rd)を入力しないと phpMyAdmin GUI は表示されません:

最低限、このようなベーシック認証で守られていれば URL が分かってもデータの内容にはアクセスできなくなります。MySQL データを GUI で見ることができる phpMyAdmin は便利ですが、インターネットアクセスを許可する場合は最低限このような方法でデータを守る必要があります。最近はコンテナ環境を使うケースも増えていると思うので、そんな人の参考になれば。





