Macや Linuxでは Windowsの A5:SQLのようなアプリケーションがなかったりあったりします。個人的にはコマンドが使えれば大抵のことは問題ないのですが作業によっては GUIの方が効率が良いこともあります。また、たまに他人の PC でデータベースを見に行ったりということもあるのですが、他人の PC に新しいアプリケーションをインストールしてセットアップして…というのはなかなか億劫です。
案件によってはお客さんが利便性優先で(というかデータベースはそうやって扱うものだと思っていることもあり)アプリケーションサーバに phpMyAdminを設置してしまっていることがあります。しかし、実際に稼働しているアプリケーションサーバに phpMyAdminを設置するのはリソース的にもセキュリティ的にも好ましいとは思えません。かと言って専用のサーバを用意するとコストがかかりますし、管理の手間が増えます。
そこで、エンジニアの PC には大抵入っているはず(?)の Docker でローカルに phpMyAdminコンテナを作って、そこからリモートのデータベースに接続しに行くという方法を取ります。
リモートデータベースに接続しに行くと言ってもデータベースは外部に公開されていないことがほとんどだと思います。よくあるのは AWSで EC2 と RDS を使うときに RDS がパブリックアクセス不可(デフォルト)になっている場合です。
今回は更にアプリケーションサーバの前に踏み台サーバがあり、アプリケーションサーバのみがデータベースにアクセス出来る環境で SSHと Docker を組み合わせる必要があるケースを想定しています。
phpMyAdminコンテナからリモートのデータベースに接続する
SSHポートフォワーディングの設定
ローカルからデータベースへトンネリング接続出来るようにしておきます。踏み台が無い場合は ProxyJump
を省略出来ます。ssh_config
に関する説明はここでは割愛します。
HostbastionHostNamexxx.xxx.xxxHostappHostNameyyy.yyy.yyyProxyJump bastion LocalForward13306xxx.xxxxxxx-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com:3306
コンフィグを書かずにコマンドラインで踏み台経由のトンネリングを行う場合は下記のようなコマンドになります(踏み台サーバが 192.168.1.2
、アプリケーションサーバが 192.168.1.3
の場合)。SSHのその他のオプションについては割愛します。
ssh -oProxyCommand='ssh -W %h:%p 192.168.1.2'-L 13306:xxx.xxxxxxx-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com:3306 192.168.1.3
phpMyAdminコンテナの起動
SSH接続を確立した状態にしておきます。
大抵の場合、phpMyAdminコンテナから接続しに行くのは MySQLコンテナですが、今回はコンテナから接続しに行くホストを host.docker.internal
としてホスト OS を指定します。ポートには SSHでポートフォワーディングしている 13306
を指定します。
docker run --rm-p 8080:80 -ePMA_HOST=host.docker.internal -ePMA_PORT=13306 phpmyadmin/phpmyadmin
phpMyAdminのデフォルト設定ではアップロード可能なサイズが PHPデフォルトの 2048 KB になっています。これは少ないことがあるので phpmyadmin
コンテナ独自の UPLOAD_LIMIT
環境変数でサイズを増やしておくといいかもしれません。PMA_USER
と PMA_PASSWORD
環境変数も指定することも可能ですが、コマンドの履歴に残ってしまうのでセキュリティ要件に応じて指定した方がいいでしょう。
docker run --rm-p 8080:80 -ePMA_HOST=host.docker.internal -ePMA_PORT=13306-eUPLOAD_LIMIT=1G phpmyadmin/phpmyadmin
phpMyAdminコンテナにアクセスする
phpMyAdminコンテナが起動したらホスト OS のブラウザで localhost:8080
にアクセスすればホスト OS でポートフォワーディングしているポートを経由してリモートのデータベースに接続しに行くことが出来ます。
Docker Comose の利用
毎回 docker
コマンドで実行するのは手間なので docker-compose.yml
を作成しておいて簡単に起動出来るようにしておきます。
プロジェクト毎にコンテナ名を指定してもかまいませんが、docker-compose.yml
を格納するディレクトリでコンテナ名が自動的に決まるのでコンテナ名を指定せずとも ディレクトリ名_サービス名_番号
というコンテナが作成されるためここでは指定しません。
environment
は必要に応じて設定しておきます。ユーザ名やパスワードを docker-compose.yml
に記述したくない場合は外部ファイルに記述した内容を env_file
で読み込むようにするといいでしょう。
version:'3'services:phpmyadmin:image: phpmyadmin/phpmyadmin ports:- 8080:80 environment:- PMA_HOST=host.docker.internal - PMA_PORT=13306 - PMA_USER=mysql_user - PMA_PASSWORD=mysql_password - UPLOAD_LIMIT=1G
docker-compose.yml
を任意のディレクトリに保存します。
. | +-- MyProject/ | +-- docker-compose.yml
docker-compose.yml
を保存したディレクトリに移動して docker-compose up
するか、-f
で設定ファイルを指定します。いずれの方法でもコンテナ名は MyProject_phpmyadmin_1
のようになります。
cd MyProject
docker-compose up
docker-compose -f MyProject/docker-compose.yml up
ひとつの docker-compose.yml で複数環境の phpMyAdminコンテナを定義する
Docker Compose ではサービス毎にコンテナを起動することが出来るので下記のように環境ごとの設定を書いておけば phpMyAdminを同時起動することが出来ます。これはそれぞれの環境の内容を比較したり、片方の phpMyAdminエクスポートしてきて片方の phpMyAdminでインポートするような作業のときに便利です。
version:'3'services:phpmyadmin_prod:image: phpmyadmin/phpmyadmin ports:- 8080:80 environment:- PMA_HOST=host.docker.internal - PMA_PORT=13306 - PMA_USER=mysql_user - PMA_PASSWORD=mysql_password - UPLOAD_LIMIT=1G phpmyadmin_dev:image: phpmyadmin/phpmyadmin ports:- 8081:80 environment:- PMA_HOST=host.docker.internal - PMA_PORT=23306 - PMA_USER=mysql_user - PMA_PASSWORD=mysql_password - UPLOAD_LIMIT=1G
docker-compose up
の使い方は下記の通りです。
Usage: up [options] [--scale SERVICE=NUM...] [SERVICE...]
SSH接続を確立した状態で必要に応じてコンテナを起動します。
docker-compose up
docker-compose up phpmyadmin_prod
docker-compose up phpmyadmin_dev