mattintosh note

どこかのエンジニアモドキの備忘録

macOSやLinuxからMySQLサーバにGUI接続したいときにDockerでサクッとphpMyAdminを建てる

MacLinux では 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 で確認出来ます。

ssh_config

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 のその他のオプションについては割愛します。

Terminal (macOS)

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

Terminal (Linux)

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 を指定します。

Terminal (macOS)

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_USERPMA_PASSWORD 環境変数も指定することも可能ですが、コマンドの履歴に残ってしまうのでセキュリティ要件に応じて指定した方がいいでしょう。

Terminal (macOS)

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(名前は任意)を追加で指定します。

Terminal (Linux)

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 でポートフォワーディングしているポートを経由してリモートのデータベースに接続しに行くことが出来ます。

f:id:mattintosh4:20200722200258p:plain

Docker Comose の利用

毎回 docker コマンドで実行するのは手間なので docker-compose.yml を作成しておいて簡単に起動出来るようにしておきます。

プロジェクト毎にコンテナ名を指定してもかまいませんが、docker-compose.yml を格納するディレクトリでコンテナ名が自動的に決まるのでコンテナ名を指定せずとも ディレクトリ名_サービス名_番号 というコンテナが作成されるためここでは指定しません。

environment は必要に応じて設定しておきます。ユーザ名やパスワードを docker-compose.yml に記述したくない場合は外部ファイルに記述した内容を env_file で読み込むようにするといいでしょう。

docker-compose.yml (macOS)

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 (Linux)

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 でインポートするような作業のときに便利です。

docker-compose.yml (macOS)

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 の使い方は下記の通りです。

docker-compose up --help

Usage: up [options] [--scale SERVICE=NUM...] [SERVICE...]

SSH 接続を確立した状態で必要に応じてコンテナを起動します。

両環境のコンテナを同時起動する場合

docker-compose up

Prod 用のコンテナを起動する場合

docker-compose up phpmyadmin_prod

Dev 用のコンテナを起動する場合

docker-compose up phpmyadmin_dev