DockerやDocker Composeで、MySQLコンテナを起動するとき、どうしてもポートをホスト側に公開できないが、ホスト側からはDBにはアクセスしたいことがあります。
この投稿では、Mutagenを利用して、ポートを開けずとも、ホスト側からMySQLコンテナにアクセスする方法を紹介します。
この投稿が解決したいこと
この投稿が解決するのは、下記のような制約とやりたいことの板ばさみ状態です。
制約
- MySQLコンテナのポートを開けるのが面倒。
- 例えば、複数のプロジェクトに携わっていて、複数のdocker-compose.ymlがあり、それぞれにMySQLコンテナがある。
- それぞれに3306, 3307, 3308, ...と割り当てていくのは、重複を意識したり管理が面倒
- 勝手にはMySQLのポートをホスト側に公開できない。
- 例えば、MySQLのポートが空いていないdocker-compose.ymlがチームで共有されていて、設定を変更したくない。
- ポートを公開するのに消極的。
- デバッグのために、ポートを開けるのはあまり気が進まない。
やりたいこと
- Mac(ホストマシン)側からMySQLのコンテナのDBをいじりたい。
- MacのSequel ProからDBを参照したい。
- PhpStormなどのIDEから、Docker上のMySQLを参照したい。
この投稿で紹介する解決策が意味ないケース
- 普通に、
-p
,--publish
オプションでコンテナのポートが公開できる。- シンプルにこれができるなら、これがベスト。
解決策の概要
解決策の概要は、MutagenのForward機能を使って、Macの3306ポートをコンテナの3306ポートにネットワーク転送する、というものです。
Mac側にポートを公開せずに、Docker上のMySQLに接続する方法
Mutagenをインストールする
Homebrewでインストールします:
brew install mutagen-io/mutagen/mutagen
普通にMySQLコンテナを立ち上げる
MySQLコンテナは、ポートを公開しない設定で普通に起動すればOK:
docker-compose up -d
version: '3.1'
services:
db:
image: mysql
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' # 便宜上rootのパスワードは空欄にしときます
MYSQL_DATABASE: project1_db # データベース名の設定
起動したMySQLコンテナの名前をひかえる
Mutagenでネットワーク転送をかけるには、Dockerコンテナの名前を知っておく必要があるので、それを調べておきます:
$ docker-compose ps
Name Command State Ports
----------------------------------------------------------------------------
project1_db_1 docker-entrypoint.sh --def ... Up 3306/tcp, 33060/tcp
この例だと、project1_db_1
がコンテナの名前です。
Mutagenでネットワーク転送をかける
mutagen
のfoward create
コマンドでネットワーク転送をしかけます:
mutagen forward create --name project1-mysql tcp::3306 docker://project1_db_1:tcp::3306
コマンドのオプションと引数を説明すると:
-
--name project1-mysql
: ネットワーク転送管理用の名称です。ネットワーク転送を解除するときに使います。好きに決めてOK。 -
tcp::3306
: ひとつめの引数のこれは、ホスト側、つまりMac側のポートです。ここでは、3306を指定しているので、Macからはlocalhost:3306
でMySQLコンテナに繋がります。 -
docker://project1_db_1:tcp::3306
: ふたつめの引数のこれは、MySQLコンテナがEXPOSEしているポートです。Docker Hubに公開されているmysql
イメージの場合、3306がEXPOSEされているので、ここではそれを指定しています。
Mac側のMySQLクライアントで接続する
ここまでやれば、Mac側のMySQLクライアントで接続することができます:
$ mysql -uroot -h 127.0.0.1 -e 'SHOW DATABASES'
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| project1_db |
| sys |
+--------------------+
先程のdocker-compose.yml
で設定したデータベース名のproject1_db
が表示されているので、ちゃんとコンテナのDBに接続できていることが分かります。
ちなみに
Mutagenで作ったネットワーク転送は明示的に削除しない限り、残留します。
ネットワーク転送の一覧と削除は以下のコマンドでできます。
Mutagenでネットワーク転送の一覧を表示する方法
$ mutagen forward list
--------------------------------------------------------------------------------
Name: project1-mysql
Identifier: fwrd_UOiwU9MsAHe4NxTZR0iwxxCypNyL9ca2AscBhrhirfX
Labels: None
Source:
URL: tcp::3306
Connection state: Connected
Destination:
URL: docker://project1_db_1:tcp::3306
DOCKER_HOST=
DOCKER_TLS_VERIFY=
DOCKER_CERT_PATH=
Connection state: Connected
Status: Forwarding connections
--------------------------------------------------------------------------------
Mutagenでネットワーク転送を削除する方法
mutagen forward terminate project1-mysql
最後までお読みくださりありがとうございました。Twitterでは、Qiitaに書かない技術ネタなどもツイートしているので、よかったらフォローしてもらえると嬉しいです→Twitter@suin