Mac や Linux では Windows の A5:SQL のようなアプリケーションがなかったりあったりします。個人的にはコマンドが使えれば大抵のことは問題ないのですが作業によっては GUI の方が効率が良いこともあります。また、たまに他人の PC でデータベースを見に行ったりということもあるのですが、他人の PC に新しいアプリケーションをインストールしてセットアップして…というのはなかなか億劫です。
案件によってはお客さんが利便性優先で(というかデータベースはそうやって扱うものだと思っていることもあり)アプリケーションサーバに phpMyAdmin を設置してしまっていることがあります。しかし、実際に稼働しているアプリケーションサーバに phpMyAdmin を設置するのはリソース的にもセキュリティ的にも好ましいとは思えません。かと言って専用のサーバを用意するとコストがかかりますし、管理の手間が増えます。
そこで、エンジニアの PC には大抵入っているはず(?)の Docker でローカルに phpMyAdmin コンテナを作って、そこからリモートのデータベースに接続しに行くという方法を取ります。
リモートデータベースに接続しに行くと言ってもデータベースは外部に公開されていないことがほとんどだと思います。よくあるのは AWS で EC2 と RDS を使うときに RDS がパブリックアクセス不可(デフォルト)になっている場合です。
今回は更にアプリケーションサーバの前に踏み台サーバがあり、アプリケーションサーバのみがデータベースにアクセス出来る環境で SSH と Docker を組み合わせる必要があるケースを想定しています。
phpMyAdmin コンテナからリモートのデータベースに接続する
SSH ポートフォワーディングの設定
ローカルからデータベースへトンネリング接続出来るようにしておきます。踏み台が無い場合は ProxyJump
を省略出来ます。ssh_config
に関する説明はここでは割愛します。
Linux の場合は後述する host.docker.internal
が使えないため Docker のブリッジで使用するアドレスをバインドするようにします。デフォルトのブリッジねとワークの IP アドレスは docker network inspect bridge
で確認出来ます。
Host bastion HostName xxx.xxx.xxx Host app HostName yyy.yyy.yyy ProxyJump bastion LocalForward 13306 xxx.xxxxxxx-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com:3306 # for Linux LocalForward 172.17.0.1:13306 xxx.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
ssh -oProxyCommand='ssh -W %h:%p 192.168.1.2' -L 172.17.0.1: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 -e PMA_HOST=host.docker.internal -e PMA_PORT=13306 phpmyadmin/phpmyadmin
phpMyAdmin のデフォルト設定ではアップロード可能なサイズが PHP デフォルトの 2048 KB になっています。これは少ないことがあるので phpmyadmin
コンテナ独自の UPLOAD_LIMIT
環境変数でサイズを増やしておくといいかもしれません。PMA_USER
と PMA_PASSWORD
環境変数も指定することも可能ですが、コマンドの履歴に残ってしまうのでセキュリティ要件に応じて指定した方がいいでしょう。
docker run --rm -p 8080:80 -e PMA_HOST=host.docker.internal -e PMA_PORT=13306 -e UPLOAD_LIMIT=1G phpmyadmin/phpmyadmin
Linux の場合は host.docker.internal
(名前は任意)を追加で指定します。
docker run --rm -p 8080:80 -e PMA_HOST=host.docker.internal -e PMA_PORT=13306 -e UPLOAD_LIMIT=1G --add-host host.docker.internal:172.17.0.1 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
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 extra_hosts: - 'host.docker.internal:172.17.0.1'
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