2
votes

I am trying to make webpack-dev-server work on my local network with external devices. The whole project is running in WSL2 Debian 10 on windows 10. I haven't found this particular problem anywhere yet, so decided to post this.

So the project is a WordPress site running in docker, and webpack-dev-server is proxying this to port 3000 (all in WSL). Everything works as expected on the local machine: The site is available in windows on localhost:3000 and works fine.

However, I want to access this on my mobile device as well. From what I find online, this should just work when connecting to the host ip (on the right port) on the mobile device, provided it is on the same network. My pc and phone are on the same home wifi network, so that's ok.

I have tried both the wsl adapter ipv4 and the wifi adapter ipv4 addresses, but as far as I understand, if everything is connected to wifi, Wireless LAN adapter Wi-Fi should be used? So using every one of those ip's results in the following connection errors on my phone (chrome android):

  • The wsl adapter ip:3000 gives ERR_CONNECTION_TIMED_OUT, so probably not the one
  • The wifi adapter <<wifi-adapter ip>>:3000 gives ERR_EMPTY_RESPONSE
  • The wifi adapter <<wifi-adapter ip>> (without port) somehow resolves to "localhost" in the address bar and gives ERR_CONNECTION_REFUSED

I have already tried:

  • adding host: '0.0.0.0' to the webpack config.
  • forwarding port 3000 in windows using netsh interface portproxy add v4tov4 listenport=3000 listenaddress=0.0.0.0 connectport=3000 connectaddress=127.0.0.1
  • forwarding port 3000 in windows using netsh interface portproxy add v4tov4 listenport=3000 listenaddress=0.0.0.0 connectport=3000 connectaddress=<<wifi-adapter ip>>
  • disabling windows defender firewall
  • adding public: '<<wifi ip>>:3000' to the webpack config.
  • trying different ports, I tried with 5040, 8000 and 8080.
  • If I try to add host: '<<wifi-adapter ip>>' , webpack throws an error on startup: Error: listen EADDRNOTAVAIL: address not available <<wifi-adapter ip>>:3000, happens with all kind of different ports.

Every one of those had no noticeable effect in behaviour, both on the host pc and when trying to connect on LAN. I found Issues regarding webpack-dev-server not being accessible on LAN, and the usual solution is adding host: '0.0.0.0', but these issues don't mention the use of wsl. Also, similar issues that include wsl usually have the port forwarding and firewall as accepted answers, but none of that seems to have an effect in my case. I haven't found an issue and solution for this connection issue which includes wsl and webpack, so I'm really out of ideas since it's not clear to me how to troubleshoot this and see if the issue lies with either the windows host, wsl, my home network or something else? So maybe someone sees an obvious configuration mistake here? Again, it works perfectly fine on the host pc itself. Any insight is greatly appriciated.

Webpack config (only devserver part):

config.devServer = {
    before(app, server) {
        chokidar.watch([path.resolve(__dirname, './**/*.php')]).on('all', function () {
            server.sockWrite(server.sockets, 'content-changed');
        });
    },
    host: '0.0.0.0',
    contentBase: false,
    writeToDisk: true,
    inline: true,
    disableHostCheck: true,
    port: 3000,
    hot: false,
    index: '',
    proxy: {
        context: () => true,
        changeOrigin: true,
        '/**': 'http://localhost',
    },
};

The output of ipconfig is:

Windows IP Configuration

Ethernet adapter Ethernet:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . : home

Ethernet adapter Ethernet 2:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . : home

Ethernet adapter vEthernet (WSL):

   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : xxxx
   IPv4 Address. . . . . . . . . . . : 172.x.x.x
   Subnet Mask . . . . . . . . . . . : 255.255.x.x
   Default Gateway . . . . . . . . . :

Wireless LAN adapter Local Area Connection* 1:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :

Wireless LAN adapter Local Area Connection* 10:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :

Wireless LAN adapter Wi-Fi:

   Connection-specific DNS Suffix  . : home
   Link-local IPv6 Address . . . . . : xxx
   IPv4 Address. . . . . . . . . . . : 192.168.x.x <-- used this ip as <<wifi-adapter ip>>, correct?
   Subnet Mask . . . . . . . . . . . : 255.255.x.x
   Default Gateway . . . . . . . . . : 192.168.x.x

Ethernet adapter Bluetooth Network Connection:

   Media State . . . . . . . . . . . : Media disconnected
   Connection-specific DNS Suffix  . :

EDIT:

I managed to fix it using a combination of fixes, but I really need all of them or it just doesn't work:

  • port forwarding (like @Luis script, but I used this one, which includes firewall rules)
  • sometimes the port I want to use is blocked on my system for some reason and I need to kill existing processes listening on that port. However port 3000 just doesn't want to work with me on anything, so I just use 8000
  • windows fast startup disabled, which is known for messing up localhost on wsl2
  • manually enable localhost in windows hosts file (got it from here)
  • always use 0.0.0.0 as host on any server running in wsl2

Then I can access the server on my LAN network via the ip listed in windows (so the 192.168.x.x one in my case). I now use this webpack config:

config.devServer = {
        before(app, server) {
            chokidar.watch([path.resolve(__dirname, './**/*.php')]).on('all', function () {
                server.sockWrite(server.sockets, 'content-changed');
            });
        },
        host: '0.0.0.0',
        contentBase: false,
        writeToDisk: true,
        inline: true,
        disableHostCheck: true,
        port: 5000,
        hot: false,
        index: '',
        proxy: {
            context: () => true,
            '/**': {
                target: 'http://localhost',
                changeOrigin: true,
                autoRewrite: true,
            },
        },
    };

Note: for WordPress specifically I had to add another fix because none of the styles or scripts were loading when accessed from LAN, as WordPress "hardcodes" the site url in the database and then throws a bunch of not found and cors errors when accessing the site from anything other than http://localhost. That one got fixed by using wp_make_link_relative() in WordPress itself, just like this simple plugin does it.

1

1 Answers

0
votes

With netsh, your connectaddress must be WSL 2 IP, you can try this commands on powershell:

    # GET THE WSL IP AND CHECKS IT FORMAT xxx.xxx.xxx.xxx
    $WSL_CLIENT = bash.exe -c "ip addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'";
    $WSL_CLIENT -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}';
    $WSL_CLIENT = $matches[0];
    
    # ADD PORTS FORWARD FROM WSL TO WINDOWS
    #(With this command, windows port 3000 starts to listen port 3000 of wsl2)
    iex "netsh interface portproxy add v4tov4 listenport=3000 listenaddress=127.0.0.1 connectport=3000 connectaddress=$WSL_CLIENT"
    
    # TO CHECK ALL PORTS CONFIGURED:
    netsh interface portproxy show all

If the command above dont work, you can also try this one, but on wsl terminal:

    # Its the same concept, works like a proxy forwarding Linux traffic
    
    $ sysctl -w net.ipv4.conf.all.route_localnet=1
    $ iptables -t nat -I PREROUTING -p tcp -j DNAT --to-destination 127.0.0.1