Help us understand the problem. What is going on with this article?

Docker: MySQLコンテナのポートをMac側に公開せずに、MacからそのMySQLに接続する小技

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
docker-compose.yml
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でネットワーク転送をかける

mutagenfoward 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に書かない技術ネタなどもツイートしているので、よかったらフォローしてもらえると嬉しいです:relieved:Twitter@suin

suin
Qiita 4位/TypeScript入門書執筆中/TypeScripterのための座談会「YYTypeScript」主催/『実践ドメイン駆動設計』書籍邦訳レビュア/分報Slack考案/YYPHP主催/CodeIQマガジン執筆/株式会社クラフトマンソフトウェア創設/Web自動テスト「ShouldBee」の開発/TypeScript/DDD/OOP
https://yyts.connpass.com/
shouldbee
開発者向けテスト支援サービスShouldBeeを開発・運営するスタートアップ(onlab第8期)
http://shouldbee.at
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした