プログラムを中心とした個人的なメモ用のブログです。 タイトルは迷走中。
内容の保証はできませんのであしからずご了承ください。

2022/07/29

WSL2 上の Docker コンテナに外部からアクセスする

update2023/07/03 event_note2022/07/29 1:41

Ubuntu で Docker を使っている場合はホストとコンテナのポートマッピングさえ行えば外部からアクセスできました。
しかし、WSL2 を使っている場合は Windows と WSL2(Ubuntu) のポートフォワーディングの設定を行わないと外部からはアクセスできません。

尚、タイトルには「Docker コンテナに外部からアクセス」と書きましたが、Windows と WSL2 の話なので、Docker は関係ありません。

環境

  • ホスト: Windows 10
  • WSL2: Ubuntu 20.04

設定方法

WSL2 の IP アドレスを調べる

まずは WSL2 上で以下のコマンドを実行し、eth0 の IP アドレスを調べます。

$ ip addr show dev eth0

または hostname -I でも調べられます。

Windows と WSL2 のポートフォワーディング設定

コマンドプロンプトまたは PowerShell で以下のコマンドを実行します。

> netsh interface portproxy add v4tov4 listenport=<ポート> connectaddress=<WSL2のIPアドレス>

これで外部からアクセス可能になります。
設定ができているか確認したい場合は以下のコマンドを実行します。

> netsh interface portproxy show v4tov4

ipv4 をリッスンする:         ipv4 に接続する:

Address         Port        Address         Port
--------------- ----------  --------------- ----------
*               5001        172.20.93.38    5001

設定を削除したい場合は以下のコマンドを実行します。

> netsh interface portproxy delete v4tov4 listenport=<ポート>

設定の自動化

WSL2 の IP アドレスは起動の度に変わるので、Windows 起動時に自動で設定するようにします。

Windows 上で WSL2 の IP アドレスを取得

PowerShell で以下を実行します。

> $IP = wsl -d Ubuntu-20.04 exec hostname -I

しかし、私の環境では複数の IP アドレスが表示されてしまいました。

> $IP
172.20.93.38 172.17.0.1 172.18.0.1

なので、以下のようにスペースで区切って最初の IP アドレスだけを取得できるようにしました。

> $IP = (wsl -d Ubuntu-20.04 exec hostname -I).split(" ")[0]

スクリプトファイルの作成と実行

以上を踏まえ、以下のようなスクリプトファイルを作成します。

$IP = (wsl -d Ubuntu-20.04 exec hostname -I).split(" ")[0]
netsh interface portproxy delete v4tov4 listenport=<ポート>
netsh interface portproxy add v4tov4 listenport=<ポート> connectaddress=$IP

あとはこれをタスクスケジューラーでログオン時に実行するようにすれば OK です。