まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

タグ:phpmyadmin

2月も中旬に差し掛かろうとするこのタイミングで今年最初のブログエントリです。サボり癖を付けないようにしないと。。

久しぶりに phpMyAdmin を使ってみました。MySQL を使っている環境で開発していると、この手の GUI クライアントアプリが欲しくなる機会は多いはずです。アプリ開発でなくても WordPress のような CMS を使っている場合でも、こういった DB に直接アクセスできるツールがあるとちょっとしたデータ変更などにも便利ですよね:
2026021100


私自身は 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

2026021101


ここまではさほど難しくありません。


【何が問題か?】
さて、上記までは特別な要素はなくて、一般的な 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 は表示されません:
2026021102


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


IBM Cloud から提供されている 30 日間無料 Kubernetes サービスIBM Kubernetes Service 、以下 "IKS")環境を使って利用することのできるコンテナイメージを1日に1個ずつ 30 日間連続で紹介していきます。

環境のセットアップや制約事項については Day0 のこちらの記事を参照してください。

Day 7 は Day 6 で紹介した MySQL 環境を GUI で使うためのツールを紹介します。MySQL の GUI ツールは多くありますが、ウェブで(コンテナで)使えて有名なもの・・・となると、phpMyAdmin になるではないでしょうか?というわけで Day6 の内容の続きとして phpMyAdmin イメージをデプロイする例を紹介します。
phpmyadmin



【イメージの概要】
phpMyAdmin は広く使われているオープンソースのリレーショナル・データベース・サーバー MySQL を CLI ではなく、GUI から利用するためのツール(ウェブ用クライアント)です。個人的には MySQL に限らず、データベースは CLI で接続して直接 SQL で操作することが多いのですが、一方で「見やすさ・簡単さ」については CLI よりも GUI に軍配が上がることは理解していて、必要に迫られてデータベースとセットで環境を用意することが多くあります。



【イメージのデプロイ】
まずはこちらのファイルを自分の PC にダウンロードしてください:
https://raw.githubusercontent.com/dotnsf/yamls_for_iks/main/phpmyadmin.yaml


次にこのファイルをテキストエディタで開いてパラメータを編集します。具体的には以下3箇所の中の上2つ(一番下の PMA_PORT は Day 6 の設定通りに行っていれば 30306 が正しい値です)の value 値を変更してください。それぞれの具体的な意味は以下の通りです:
・MYSQL_ROOT_PASSWORD : 管理者パスワード、Day 6 の MySQL デプロイ時に指定したものと同じ値を設定(初期値 P@ssw0rd)
・PMA_HOST : 接続先 MySQL のホストまたは IP アドレス(初期値 xxx.xxx.xxx.xxx)
・PMA_PORT : 接続先 MySQL のポート番号(初期値 30306)

※PMA_HOST だけはこのままでは絶対に動きません。後述する「ワーカーノードの IP アドレス」と同じ値を指定してください。

ではこのダウンロード&編集した phpmyadmin.yaml ファイルを指定してデプロイします。以下のコマンドを実行する前に Day 0 の内容を参照して ibmcloud CLI ツールで IBM Cloud にログインし、クラスタに接続するまでを済ませておいてください。

そして以下のコマンドを実行します:
$ kubectl apply -f phpmyadmin.yaml

以下のコマンドで MySQL と phpMyAdmin 関連の Deployment, Service, Pod, Replicaset がそれぞれ1つずつ生成されたことと、サービスが 30306 番ポート(MySQL)と 30080 番ポート(phpMyAdmin)で公開されていることを確認します:
$ kubectl get all

NAME                             READY   STATUS    RESTARTS   AGE
pod/mysql-5bd77967b-799vp        1/1     Running   0          9m26s
pod/phpmyadmin-bc66b87f5-strb8   1/1     Running   0          113s

NAME                  TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
service/kubernetes    ClusterIP   172.21.0.1      <none>        443/TCP          26d
service/mysqlserver   NodePort    172.21.40.65    <none>        3306:30306/TCP   9m28s
service/phpmyadmin    NodePort    172.21.156.43   <none>        80:30080/TCP     115s

NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mysql        1/1     1            1           9m27s
deployment.apps/phpmyadmin   1/1     1            1           114s

NAME                                   DESIRED   CURRENT   READY   AGE
replicaset.apps/mysql-5bd77967b        1         1         1       9m28s
replicaset.apps/phpmyadmin-bc66b87f5   1         1         1       115s

この後に実際にサービスを利用するため、以下のコマンドでワーカーノードのパブリック IP アドレスを確認します(以下の例であれば 161.51.204.190):
$ ibmcloud ks worker ls --cluster=mycluster-free
OK
ID                                                       パブリック IP    プライベート IP   フレーバー   状態     状況    ゾーン   バージョン
kube-c3biujbf074rs3rl76t0-myclusterfr-default-000000df   169.51.204.190   10.144.185.144    free         normal   Ready   mil01    1.20.7_1543*

つまりこの時点で(上述の結果であれば)アプリケーションは http://169.51.204.190:30080/ で稼働している、ということになります。早速実行してみます。ウェブブラウザか curl コマンドを使って、アプリケーションの URL(上述の方法で確認した URL)にアクセスしてみます:
phpmyadmin1


phpMyAdmin のトップページにアクセスできました。とりあえず IKS 上で動いていることは確認できました。Day 6 で作った MySQL のデプロイ時に設定したアカウントを入力すると、データベースを GUI で操作することができるようになります:
phpmyadmin2




【YAML ファイルの解説】
YAML ファイルはこちらを使っています:
apiVersion: v1
kind: Service
metadata:
  name: phpmyadmin
spec:
  selector:
    app: phpmyadmin
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30080
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: phpmyadmin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: phpmyadmin
  template:
    metadata:
      labels:
        app: phpmyadmin
    spec:
      containers:
      - name: phpmyadmin
        image: phpmyadmin
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "P@ssw0rd"
        - name: PMA_HOST
          value: "xxx.xxx.xxx.xxx"
        - name: PMA_PORT
          value: "30306"
        ports:
        - containerPort: 80

Deployment 1つと、Service 1つのごくごくシンプルな YAML ファイルですが、一応解説を加えておきます。アプリケーションそのものは 80 番ポートで動作するように作られているため、NodePort 30080 番を指定して、外部からは 30080 番ポートでアクセスできるようにしています(NodePort として指定可能な番号の範囲は 30000 ~ 32767 です、指定しない場合は空いている番号がランダムに割り振られます)。また ReplicaSet は1つだけで作りました。


デプロイしたコンテナイメージを削除する場合はデプロイ時に使った YAML ファイルを再度使って、以下のコマンドを実行します。不要であれば(Day 6 の MySQL と一緒に)削除しておきましょう:
$ kubectl delete -f phpmyadmin.yaml


【紹介したイメージ】
https://hub.docker.com/_/phpmyadmin


【紹介記録】
Dayカテゴリーデプロイ内容
0準備準備作業
1ウェブサーバーhostname
2Apache HTTP
3Nginx
4Tomcat
5Websphere Liberty
6データベースMySQL
7phpMyAdmin
8PostgreSQL
9pgAdmin4
10MongoDB
11Mongo-Express
12Redis
13RedisCommander
14ElasticSearch
15Kibana
16CouchDB
17CouchBase
18HATOYA
19プログラミングNode-RED
20Scratch
21Eclipse Orion
22Swagger Editor
23R Studio
24Jenkins
25アプリケーションFX
262048
27DOS Box
28VNC Server(Lubuntu)
29Drupal
30WordPress

前回、LAMP 環境を構築した IBM LinuxONE サーバーを使って、PHP のメジャーな MVC フレームワークの1つであるCakePHP の環境を整えてみます:
IBM LinuxONE コミュニティクラウド上で LAMP 環境を作る


まず CakePHP を動かす場合の PHP 設定を行います。/etc/php.ini を適宜変更するのですが、最低限やっておかないといけないのが、タイムゾーンの設定です。/etc/php.ini を編集して、以下の設定を加えます([Date] カテゴリ内でコメントアウトされている Date.timezone の設定からコメントを外し、"Asia/Tokyo" に設定して保存します:
$ sudo vi /etc/php.ini

  :
  :
[Date]
Date.timezone = "Asia/Tokyo"
  :
  :

また CakePHP では PHPUnit というモジュールを使うことになるので、これもインストールしておきます。前回の LAMP 環境構築時に pear もインストールしているので、pear を使って PHPUnit を導入します:
$ sudo pear install pear/PHPUnit

次に MySQL の設定を行います。まずは文字コードの設定を変更して、デフォルトで UTF-8 を使えるようにします:
$ sudo vi /etc/my.cnf

[mysqld]
character-set-server=utf8

[mysql]
default-character-set=utf8



今回は CakePHP 専用のデータベース(cakedb)を新たに作成し、その中に商品情報を格納するマスターテーブル(items)と、商品カテゴリを格納するマスターテーブル(categories)を定義することにします:
$ mysql -u root -p

mysql> create database cakedb default character set utf8;
mysql> use cakedb
mysql> create table items( id int primary key auto_increment, name varchar(50), category_id int, created datetime default null, modified datetime default null );
mysql> create table categories( id int primary key auto_increment, name varchar(50), created datetime default null, modified datetime default null );
mysql> quit

1つのデータベースと、2つのテーブルを作りました。必要に応じてこれらにアクセスできるユーザーなどを追加しましょう。

これら2つのマスターテーブルを操作できるような環境を CakePHP で作ることにしましょう。ここは必須ではありませんが、データベースを操作する上では phpMyAdmin があると便利です。IBM LinuxONE コミュニティクラウドのサーバーに phpMyAdmin 環境を導入する場合の手順はこちらの記事を参考にしてください:
IBM LinuxONE コミュニティクラウド上に phpMyAdmin を導入する


ではいよいよメインディッシュの CakePHP 環境を構築します。PHP 5.3 でも動くよう、CakePHP のバージョンは 2.x を使うことにします。またこれも Apache HTTPD のドキュメントルートがデフォルトのままの /var/www/html であるとして作業を紹介します:
$ https://github.com/cakephp/cakephp/archive/2.9.4.zip
$ sudo /bin/bash
# cd /var/www/html
# unzip ~linux1/2.9.4.zip
# mv cakephp-2.9.4 cakephp
# chmod 777 -R cakephp/app/tmp
# chmod 755 cakephp/lib/Cake/Console/cake
# cd cakephp/app/Config
# vi core.php

  :
  :
/**
 * A random string used in security hashing methods.
 */
        Configure::write('Security.salt', 'ABCDabcd1234');

/**
 * A random numeric string (digits only) used to encrypt/decrypt strings.
 */
        Configure::write('Security.cipherSeed', '1234567890');
  :
  :

最後の cakephp/app/Config/core.php の編集作業では 'Security.salt' の値と、'Security.cipherSeed' の値はデフォルトの(既知の)値のままだと危ないのでランダムな値に書き換えました。

続けて(カレントディレクトリが cake/app/Config/ の状態で)、更にデータベースの設定ファイルを用意して、自分の環境に合わせた設定を行います:
# cp database.php.default database.php
# vi database.php

  :
  :
class DATABASE_CONFIG {

        public $default = array(
                'datasource' => 'Database/Mysql',
                'persistent' => false,
                'host' => 'localhost',
                'login' => 'root',
                'password' => 'P@ssw0rd',
                'database' => 'cakedb',
                'prefix' => '',
                //'encoding' => 'utf8',
        );
  :
  :

↑具体的にはユーザー名(login)、パスワード(password)、データベース(database)の値を書き換えます。


CakePHP 自体はここまでの設定で動くはずです。必要に応じて DebugKit などの便利なプラグインを cakephp/app/Plugin/ 以下に追加で導入してください。DebugKit の導入に関してはこちらを参照ください:
https://github.com/cakephp/debug_kit/tree/2.2


ブラウザで http://(IPアドレス)/cakephp/ にアクセスすると、CakePHP のホーム画面が表示されます。緑と黄色のバーが並んでいる状態であれば、少なくとも設定は間違っていないことになります。下図では DebugKit まで導入して、全て緑になっている状態です:
2017010603

 

IBM LinuxONE コミュニティクラウド上に LAMP 環境のサーバーを作り、そのデータベースを管理するための phpMyAdmin を導入します。LAMP 環境を作るまでの手順は以下を参照してください:


LAMP 環境が出来てしまえば phpMyAdmin は普通に導入できるのでは・・・ と考える人がいるかもしれません。ほぼ正解ですが一点だけ注意点があります。

2017/Jan/06 時点では、IBM LinuxONE コミュニティクラウドの RHEL 6.x で提供されている PHP のバージョンは 5.3.3 です。一方で phpMyAdmin の最新バージョンは 4.6.5.2 ですが、こちらは PHP 5.5 以上を動作環境としています。つまり現時点の LinuxONE 環境では phpMyAdmin 最新バージョンの動作条件を満たすことができないのでした。

というわけで、PHP 5.3.3 でも動作できるバージョンの phpMyAdmin 4.0.x を用意する必要があります。この一点だけが注意点なのでした。


では改めて、こちらの手順を参考に IBM LinuxONE コミュニティクラウド上に作った仮想サーバーに SSH でログインします:
2017010403


では phpMyAdmin 4.0.x(2017/Jan/06 時点の最新版は 4.0.10.18)を導入します。Apache HTTP サーバーのドキュメントルートはデフォルトの /var/www/html であると仮定して、以下を実行します:
$ wget https://files.phpmyadmin.net/phpMyAdmin/4.0.10.18/phpMyAdmin-4.0.10.18-all-languages.zip
$ sudo /bin/bash
# cd /var/www/html
# unzip ~linux1/phpMyAdmin-4.0.10.18-all-languages.zip
# mv phpMyAdmin-4.0.10.18-all-languages phpMyAdmin
# exit

これで http://(IPアドレス)/phpMyAdmin/ にアクセスすれば phpMyAdmin にアクセスできます。必要に応じて認証をつけた上で運用してください:
2017010602



以前にこんなブログエントリを書きました:
StrongLoop のデモ用 MySQL サーバー


残念なことに 2016/Dec/02 現在、ここで紹介した Strongloop からのサンプル MySQL データベースの情報は消えてしまいました。。。

というわけで、改めて公開されている MySQL データベースを探していたのですが、その経緯でこんなサイトを見つけました:
http://db4free.net/
2016120200


db4free.net はその名の通り、無料でテスト用の MySQL データベースを作成できるサービスのようです。最新バージョンである MySQL 8 にも対応している模様です。本番環境としての利用は推奨されていませんし、パフォーマンスの担保もありませんが、200 MB までの MySQL データベースを1つ作れるようです。また作成後は phpMyAdmin による管理にも対応しています:
2016120201


私も実際に1つ作ってみました。はっきり言ってウェブインターフェースの(phpMyAdmin の)パフォーマンスはかなり遅いのですが、コマンドラインから直接 MySQL DB に接続して使っている分には、まあまあ使えると思っています。ちなみに作成したデータベースのデフォルト文字コードは UTF-8 でした:
2016120202


これでサンプルテーブルを作り、サンプルデータをロードすれば OK 。データの削除権限を持ったユーザーなので、ユーザー情報を公開するわけにはいきませんが、当初の目的(汎用的に使えるサンプル MySQL データベースの公開)を達成することはできそうです。

このページのトップヘ