はじめに
windows側のクライアントからWSL上のDocekrコンテナで稼働させているMySQLへlocalhost経由で接続できな問題が発生しました。
初歩的な問題でしたが、解決までに意外と時間を取られてしまったため、備忘録として解決方法をまとめます。
(本記事ではWSLはWSL2を指します。)
事象の再現
以下のような構成でwindows側のクライアントからMySQLへ接続を試みました。
MySQLはWSl内でdockerコンテナとして起動しています。
windows側で以下コマンドを実行してlocalhost経由で接続してみます。
$ mysql -h localhost -u root -p
すると次のようなエラーになり接続できないです。
エラーメッセージを見ると、MySQL自体は起動していそうですがlocalhost経由での接続になにか問題がありそうなことが分かります。
ERROR 1130 (HY000): Host 'localhost' is not allowed to connect to this MySQL server
原因
今回の原因は、windows側とWSL内の両方でMySQLが稼働していたことにありました。
接続先をlocalhostに指定していたため、想定したWSL内のMySQLではなくwindows側のMySQLに接続しようとしていました。
解決方法
方法① windows側のMySQLサービスを停止する
windows側でMySQlが起動しているとWSL側ではなくwindows側の方に接続されてしまいます。
そのためwindowsのサービス一覧からMySQL80を停止させます。
(あわせてスタートアップを手動にすると不要な自動起動を防げます)
それにより、pc端末内で稼働するMySQLはWSL内のみとなり、接続できるようになります。
サービス一覧の確認方法
方法② ポートフォワーディング
Dockerコンテナの設定で、ポートフォワーディングを設定し、windows側のあるポートとWSL内コンテナのMySQLのポートを紐づけます。
通常のDockerとDocker composeで本質的には同じですが少し設定方法が異なるためそれぞれポートフォワーディングの設定方法をまとめます。
a. 通常のDockerコンテナ起動
$ docker run -d -p 13306:3306 -e MYSQL_ROOT_PASSWORD=root mysql:8.0
上記コマンドのポートフォワーディング設定箇所は-p 13306:3306の部分です。
これはホスト側(windows側)の13306ポートとコンテナ側の3306ポートを紐づけていることを示します。
b. Docker composeでコンテナ起動
以下のdocker-compose.ymlでポートフォワーディングを設定します。
services:
db:
image: mysql:8.0
container_name: hoge
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: hoge
ports:
- "13306:3306"
volumes:
- db_data:/var/lib/mysql
- ./init:/docker-entrypoint-initdb.d
volumes:
db_data:
上記コマンドのポートフォワーディングの設定箇所は以下の部分です。
内容はa.にある通常のDockerコンテナ起動と同じです。
ports:
- "13306:3306"
aとbいずれかのコンテナ設定により、windows側で13306ポートを指定することWSL内のMySQLへ接続できるようになります。
$ mysql -h localhost -u root -p --port=13306
方法③ localhost経由ではなくWSl側のIPアドレス経由で接続する
localhostはwindows側とWSL側両方に存在します。
そのためwindowsとWSLの双方で同じポートがバッティングしていると論理的に近い方(windows側から接続する場合windows側のポートへ)に接続されます。
そこでWSL側のIPアドレスを直接指定することでダイレクトに接続できます。
WSL側のIPアドレスは以下コマンドで確認します
$ ip a
多数のNICが出力されますが、見るNICはeth0です。この場合、IPアドレスは172.30.76.187になります。
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:15:5d:0a:d7:7b brd ff:ff:ff:ff:ff:ff
inet 172.30.76.187/20 brd 172.30.79.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::215:5dff:fe0a:d77b/64 scope link
valid_lft forever preferred_lft forever
すると次のようにホスト名をIPアドレスにして接続できます。
$ mysql -h 172.30.76.187 -u root -p
※ ただしこのIPアドレスは再起動により変更されることがあるので注意です。
以上の3つが、Windows側からWSL内のDocker上で稼働しているMySQLに接続できない場合の主な解決方法です。


