To access an application running in a WSL2 instance from a device in a local network, you'll need to route incoming traffic to your WSL2 instance.
You can do it two ways:
The Ngrok way
This is the easiest way. Just:
Download and install ngrok.
Run
ngrok http http://localhost:PORT
, wherePORT
is the port you want to expose.You'll get an output that looks like the following:
ngrok (Ctrl+C to quit) Introducing Pay-as-you-go pricing: https://ngrok.com/r/payg
Session Status online
Account ACCOUNT NAME
Version 3.4.0
Region South America (sa)
Latency -
Web Interface http://127.0.0.1:4040
Forwarding https://81d0-123-45-6-100.ngrok-free.app -> http://localhost:3000
Connections ttl opn rt1 rt5 p50 p90
0 0 0.00 0.00 0.00 0.00
- Get the first address under
Forwarding
(https://81d0-123-45-6-100.ngrok-free.app
) and use it to access your application from anywhere on the planet that has internet access.
That should get you covered. For more details, check out Ngrok docs.
The other way
I didn't come up with this, obviously. I got this fine information from this video from David Bombal.
Here's how the other way works:
1. Grab the IP address of the host machine in your local network.
To do so, open PowerShell on the host machine and run ipconfig
.
You'll get a bunch of text, but we are looking for this piece of information:
Wireless LAN adapter Wi-Fi:
Connection-specific DNS Suffix . :
IPv4 Address. . . . . . . . . . . : 192.168.0.2
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.0.1
The IPv4 Address
value, which in this case is 192.168.0.2
, is what you need. Then...
2. Get the IP address of your WSL2 instance running on your host machine
Instead of using PowerShell on the host machine, open the shell on your distro that's running in WSL2.
As I'm using Ubuntu, I ran ip addr | grep eth0
. You'll get something like this:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
inet 172.29.19.152/20 brd 172.29.31.255 scope global eth0
Again, the information that matters here is the IPv4, but the one with the /20
mask, which is 172.29.19.152
. That's the IP address of your WSL2 instance under the host machine.
3. Doing the thing
We found out that the IP of the host machine in the local network is 192.168.0.2
, the IP of the WSL2 instance in the host machine is 172.29.19.152
.
Now, I want to run a web server on, say, port 3000
. How can I expose the web server to the local network?
It's simple. Open a PowerShell instance as an Administrator and run the following command:
netsh interface portproxy add v4tov4 listenport=<host-machine-port> listenaddress=0.0.0.0 connectport=<wsl2-instance-port> connectaddress=<wsl2-instance-ip>
Replacing the values in, we get the following:
netsh interface portproxy add v4tov4 listenport=3000 listenaddress=0.0.0.0 connectport=3000 connectaddress=172.29.19.152
After executing that, incoming traffic from the network to the host machine (192.168.0.2:3000
) will be routed to your WSL2 instance (172.29.19.152:3000
).
So go ahead, grab your phone or any other device, and try reaching 192.168.0.2:3000
. It should work.
Note that the IP of your WSL2 will likely change after you reboot your machine or the WSL2 instance. In that case, you'll need to grab the new WSL2 IP and run the PowerShell command again. It is annoying, but it is what it is.
But it didn't work!
If it's still not working after doing everything I told you to do, then you'll need to update your firewall rules.
I won't get into details, but you should create an inbound rule for your firewall, allowing TCP connections to the specific ports you want to unlock. In our example, it's port 3000
. My advice is to name the rule something along the lines of "WSL2 Unlock". Otherwise, believe me, you won't find it.
It should look like this:
Now it should be working fine and you should be able to get back to work.
If it still doesn't work you can always use Ngrok.