71

I am using windows 10 and I have ubuntu 16.04 installed as linux subsystem. I am running a rails app on port 4567, which I want to access from windows.

I know an approach of using ip address, but ifconfig didn't work. (I tried running /sbin/ifconfig). This outputs a warning as, Warning: cannot open /proc/net/dev (No such file or directory). Limited output.

I searched in internet, came across this open issue. So is there any alternative feasible solution?

4
  • 1. The Ubuntu on Windows is based on 14.04. 2. You could simply use a VM. It's easier to setup, probably has a GUI (if you want one) and supports all the features you need.
    – GiantTree
    Oct 5, 2016 at 20:41
  • Well I upgraded it to 16.04.1. GUI not needed. V.M. makes system slow.
    – peeyushsrj
    Oct 5, 2016 at 20:44
  • Well, you could run Rails directly on Windows, removing Linux completely.
    – GiantTree
    Oct 5, 2016 at 20:46
  • For that windows needs to install ruby, devkit, rails etc. which makes system slow again.
    – peeyushsrj
    Oct 5, 2016 at 20:54

6 Answers 6

79

The answer to this is surprisingly simple which is why searching isn't giving you the right results.

All that WSL does is provide a translation layer between the Linux apps and the windows kernel, very much like how Wine works on Linux. Because of this some core parts of the Ubuntu system are just not there, networking being one of them. WSL translates the Linux system calls into windows ones so the Ubuntu network data flows through the exact same TCP/IP stack as the windows data.

In short this means to access the Linux localhost you just access the windows one, they are the same. localhost:4567 or 127.0.0.1:4567 will do what you want.

As an aside I've been using rails on WSL, it seems to work perfectly except the swing and listen gems don't play well, I had to disable them.

4
  • 5
    It does work :) Installed Ubuntu, Nginx on it, started Nginx and now I can open localhost on windows :) Thanks Jul 24, 2018 at 20:39
  • Nope, doesn't work for me. I'm on the latest WSL1 version. Apr 14, 2020 at 16:24
  • python3 -m http.server How does this will work? Jun 17, 2020 at 15:00
  • Worked for me on Windows 11 and WSL2 with an embedded Tomcat as the target server Mar 22 at 4:56
28

I needed to access my WSL-hosted port from another device in my LAN
(e.g. for mobile development), and I found @Owen Tourlamain's answer of didn't help for that.

I needed to set up portproxy, and I found that using connectaddress=localhost or connectaddress=127.0.0.1 did not work for me (WSL2, Windows 10 20H2).

So I still needed the answer the the OP's question, and it turns out it's surprisingly simple:

  1. Startup WSL
  2. wsl hostname -I
    
    Output like: 172.10.200.10

Note:
You have to trim whitespace if you're using it inline in a powershell command, e.g.:

netsh interface portproxy add v4tov4 listenport=19000 listenaddress=0.0.0.0 `
    connectport=19000 connectaddress=$($(wsl hostname -I).Trim());

Accessing WSL from your network

The OP asked about accessing WSL "from windows". If you want to also access it "from your private network", you'll also need to, one time, make a firewall rule allowing a specific port (or range of ports).

⚠️ Warning: Do not turn Windows firewall "off". Make a rule to open only specific ports that you need.

(powershell as Admin)

New-NetFireWallRule -Profile Private -DisplayName 'MyRule ports for LAN development' `
    -Direction Inbound -LocalPort 19000-19006 -Action Allow -Protocol TCP

Note:

  • -LocalPort 19000-19006 ← Replace the 19000-19006 with the port(s) you need.
  • -Profile Private so that the ports are only open a network that you've marked as being "Private"
  • -Direction Inbound means inbound (ingress) only
  • -DisplayName 'MyRuleName blah blah...' is for you, human-readable name. But pick something you'll remember, because you can use this name to find the rule in the future, to view its status or to delete it. e.g. Get-NetFirewallRule | Where-Object {$_.DisplayName -Match "MyRuleName.*"}
1
  • 3
    netsh interface portproxy delete v4tov4 listenport=19000 listenaddress=0.0.0.0 for those who need it
    – TyCox94
    Mar 28, 2021 at 20:38
10

Old question that was bumped today via another answer, so I'll chime in. This question was originally asked for WSL1. While the "answer" is the same for WSL2, there are some slight differences that need to be addressed.

First, on WSL1, as the original accepted answer from 2016 mentions, the network is really running on the Windows host interface. That's why localhost/127.0.0.1 (or the address of the Windows NIC) works there.

WSL2, on the other hand, runs virtualized, so the network interface is a vNIC with a different address than that of the Windows host. That network is actually NAT'd behind the Windows host. This is also why you can access a WSL1 instance using the Windows IP address from another machine on the network, but no so with WSL2.

But WSL2 does have a feature known as "localhost forwarding", which makes it work like WSL1 for localhost/127.0.0.1. This feature is turned on by default, but can be disabled (although I don't know of any reason for ever doing so, honestly).

This feature allows you to access a service (like a Rails app, in this question). If the port isn't in use on the Windows NIC, then WSL2 will auto-forward the localhost request to the same port on the WSL2 vNIC.

So all is well and good, and you can access both WSL1 and WSL2 services via localhost, right?

Not so fast, unfortunately. Sometimes, as two other answers have mentioned, localhostForwarding "breaks". We've identified two very common (and related) use-cases where this will happen:

  • When the host Windows is hibernated.
  • When the host Windows is powered on using Windows "Fast Startup" feature, which turns out to be enabled by default. This feature uses a form of hibernation.

The solution is:

  • Don't hibernate if possible
  • Turn off Fast Startup. You'll find it in the Control Panel. Navigate to Hardware and Sound -> Power Options -> Change what the Power Buttons do
  • If you do find yourself in a situation where the feature is not working, as @AhmetK's answer mentioned, you can typically recover localhost forwarding by:
    • Exiting all running WSL instances
    • Issuing wsl --shutdown (from PowerShell, CMD, or even the Start Menu). While a full Windows restart will have the same effect, a wsl --shutdown is much faster.
    • Restart your WSL instance and running services/apps.

Reference the comments on this SO answer which have confirmed the issue and solution.

5
  • 1
    Note: wsl --shutdown did not help at my side until I ran it as administrator.
    – Tino
    Aug 24, 2022 at 20:05
  • Is there a workaround that doesn't require restarting WSL? Like using an IP address instead of localhost? (I tried the wsl hostname -I suggestion from above, but got connection refused)
    – aschmied
    Nov 17, 2022 at 23:46
  • OH! My Linux service was binding to localhost instead of 0.0.0.0 so it was only visible from localhost. Windows is a non-local host when I'm accessing the WSL host using its IP address.
    – aschmied
    Nov 17, 2022 at 23:53
  • @aschmied Good point - A bit of a trade-off. Either localhost, which works without additional configuration (but sometimes breaks, especially on hibernate) or IP address, which is reliable, but is treated as a separate network. Nov 18, 2022 at 0:08
  • @Tino might be right. I didn't try as admin. Non-admin wsl --shutdown didn't help me. I did a full restart of Windows, and that did. Now localhost:3000 loads my Next.js server running on WSL2.
    – Ryan
    Oct 19, 2023 at 23:59
4

As a temporary solution, if it stops working on WSL2, you can just shutdown WSL and run it again from PowerShell or CMD. I don't know why, but it somehow fixes this problem temporarily:

wsl --shutdown
wsl
2
  • 1
    I've provided more detail on the why (and how to avoid it in the first place) in another answer. As for the community review comment on the question, I can vouch for this answer being valid in-and-of-itself. Nov 29, 2021 at 20:58
  • 1
    Note: You probably need to run wsl --shutdown as administrator. Running it as normal user made situation worse at my side, as even the previously working ports on localhost were gone.
    – Tino
    Aug 24, 2022 at 20:02
1

After working fine for a while, I had this issue on Win10 19042 with WSL2 after installing Docker (the new WSL version), and had to restart my computer for localhost to work again.

1

For me nothing from previous answers helped; I've even gone so far as to reinstall WSL and it didn't help. Finally, the only thing that did help is:

  1. opening the .wslconfig file and setting localhostforwarding=false
  2. restarting wsl via wsl --shutdown and wsl
  3. setting the localhostforwarding=true in .wslconfig
  4. restarting wsl again

After step 4), localhost forwarding started working again. I have no idea what caused the issue in the first place, or why only this helped, but hopefully it'll save someone else couple of days of frustration

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .