I am running a simple web server on https://0.0.0.0:4000 (accessible also as https://local.phx-cd.shoepping.at:4000 with mapping to 127.0.0.1 in Ubuntu hosts file) on my WSL2 Ubuntu. I can connect to it from both Ubuntu and Windows host - so far so good. But additionally, in my Docker for Win with WSL2 integration, I run a selenium chrome container which is connecting and testing stuff on that web server (using bridge), but it can't connect to it!
I connected to the container and tried to curl to the web server - connection refused. Since I have dual boot on my computer, I tried to switch to my Linux distro, run web server there and selenium in Linux Docker and connection to the local web server worked. So I think it has something to do with the WSL2.
My docker-compose.yaml (I left out my selenium hub config)
selenium-chrome-local:
image: selenium/node-chrome-debug:3.141.59
restart: always
ports:
- 5901-5902:5900
volumes:
- /dev/shm:/dev/shm
- ../../temp:/home/seluser/Downloads
depends_on:
- selenium-hub-local
environment:
- SCREEN_WIDTH=1920
- SCREEN_HEIGHT=1080
extra_hosts:
- "local.phx-cd.shoepping.at:10.99.99.1"
networks:
- selgrid
- dockerhost
networks:
selgrid:
dockerhost:
driver: bridge
ipam:
config:
- subnet: 10.99.99.0/24
Let me know if you need more config. Thanks.
Are you sure that the Ubuntu WSL2 instance is running bridged? By default, WSL2 instances run NAT'd (whereas WSL1 instances ran bridged). So, while yes, the Docker network is bridged, it still can't access the NAT'd WSL2 VM without some extra work.
I'm fairly sure that you are running into the root problem described in WSL issue #4150. If so, here are some things to try ...
There are several workarounds suggested in that Github issue, but the basics that would work for your case boil down to forwarding port 4000 from the Windows host interface to the WSL2 instance's private IP address. In PowerShell:
netsh interface portproxy delete v4tov4 listenport="4000" # Delete any existing port 4000 forwarding
$wslIp=(wsl -d Ubuntu -e sh -c "ip addr show eth0 | grep 'inet\b' | awk '{print `$2}' | cut -d/ -f1") # Get the private IP of the WSL2 instance
netsh interface portproxy add v4tov4 listenport="4000" connectaddress="$wslIp" connectport="4000"
Note that you'll need to do this after each reboot, or else set up a script that runs at logon as described in the Github issue (see this comment).
I would also propose that, assuming it fits your workflow and if your web app runs on it, you can simply use WSL1 instead of WSL2. You can try this out by:
wsl --export <DistroName> <FileName>
wsl --import <NewDistroName> <InstallLocation> <FileNameOfBackup> --version 1
It's possible to simply change versions in place, but I tend to like to have a backup anyway before doing it, and as long as you are backing up, you may as well leave the original in place.
socat
forwarding or tunnelWhile I haven't tested your particular use-case directly, I have played around with socat
in WSL2 with success. From the looks of it socat
could be used for port forwarding from WSL2 to (at the least) the Windows host (which would be accessible to the Docker container. See this comment and example on Github about a similar use-case as yours.
The Github thread referenced above also has some details on how to enable bridge-mode on the WSL2 interface using Hyper-V. I believe this requires Windows 10 Professional or Enterprise. It also has to be done after each reboot, as with Option 1. Again, probably overkill for this case, if port forwarding or WSL1 can accomplish what you need.
Run this command on PowerShell as Administrator:
Replace {#requiredWindowsPort}
with the port that will be used in the browser
Replace {#requiredWSL2Port}
with the port running in WSL2 you want to connect to.
netsh interface portproxy add v4tov4 listenport={#requiredWindowsPort}
listenaddress=0.0.0.0 connectport={#requiredWSL2Port}
connectaddress=$($(wsl hostname -I).Trim());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With