別 PC から WSL2 内のサーバーへのアクセス
Windows の WSL2 環境で Docker コンテナを動かしているとき、そこで起動した Web サーバーなどへは、LAN 内の別 PC からはデフォルトではアクセスできません。
LAN 内の別 PC ---> Windows ---> WSL2 (Docker)
このようなアクセスを許可するには、Windows のコマンドプロンプトを管理者として実行し、次のように netsh interface portproxy
コマンドでポートフォワード設定をしてやる必要があります。
netsh
ユーティリティ(ネットワークサービスシェル)は、Windows 上の様々なネットワーク構成を設定/参照するためのコマンドです。
上記の例では、外部からの Windows の 80 番ポートへのアクセス (0.0.0.0:80
) を、WSL2 の 80 番ポート(この例では 172.28.72.28:80
)へ転送するように設定しています。
現在のポートフォワード設定 (portproxy) は次のように確認できます。
必要のなくなったポートフォワード設定は、次のように削除できます(Windows を再起動することでも削除できます)。 削除するときは、転送元のアドレスとポートを指定するだけで OK です。
ちなみに、転送先となる WSL2 の IP アドレスは、WSL2 側の bash シェルで、ip a
コマンドで調べることができます。
通常は eth0
デバイスに割り当てられた IPv4 アドレス (inet) の部分を参照すれば OK です。
Windows 側から直接実行したい場合は、wsl -e
コマンドが使えます。
C:\> wsl -e ip a show dev eth0
適当な Web サーバーコンテナを起動して試してみる
今回の構成で接続テストするには、次のように WSL2 側で軽量な nginx コンテナを立ち上げてしまうのがお手軽です。
# Windows から WSL2 の bash シェルを起動
C:\> bash
# WSL2 側で Docker デーモンを起動
maku@win:/mnt/c$ sudo service docker start
# nginx コンテナを起動
maku@win:/mnt/c$ docker container run --rm -p 8000:80 nginx:alpine-slim
ここでは、コンテナを -p 8000:80
オプション付きで起動し、ホスト側の localhost:8000
へのアクセスを、コンテナの 80
番ポートに転送するよう設定しています。
この状態で、Windows 上のブラウザから http://localhost:8000/
を開くと、WSL2 側の Web サーバーにアクセスできるはずです(WSL2 では、デフォルトで Windows 側の localhost
へのアクセスを、WSL2 側に転送してくれるようになりました)。
ただし、この時点では、外部の PC からはまだアクセスできません。 次のように Windows 上でポートフォワード設定を追加する必要があります。
# 管理者権限でコマンドプロンプトを開いてポートフォワード設定
C:\> netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8000 connectaddress=172.28.72.28 connectport=8000
ここでのポイントは、転送先のポート番号を 8000
と指定するところです (connectport=8000
)。
80
番ポートを使っているのは、あくまで WSL2 の中の Docker コンテナなので、外側からのアクセスには、コンテナ起動時に公開した 8000
番ポートの方を使う必要があります。
これで、外部の PC から WSL2 内の Docker サーバーへアクセスできます(例えば、192.168.1.100:8000
などで)。
٩(๑❛ᴗ❛๑)۶ わーぃ
将来的には Windows のポートフォワード設定がいらなくなる?
下記のマイクロソフトのページに、Microsoft は、このエクスペリエンスを改善する方法を検討しています という記載があります(2023-01 時点)。
毎回、netsh
でポートフォワード設定を行うのはさすがに面倒なので、この改善が早く実装されるとよいですね。