WSL2 and native Docker support, I thought this would be the perfect time to give them a try. One week in, I’m satisfied with my decision. But this new setup came with its own set of challenges that I’m going to discuss in this post and share my solutions with you.
Before we go any further, it is wise to discuss what my current setup is. I’m running Windows 10 Education build 19041.172. You need a build later than 18917 to enable WSL2. After following a tutorial [like this one] to enable this feature, which includes joining the insider preview program (which is free), you would need to setup something like Ubuntu 18 from the Windows store.
On my Ubuntu on WSL2, I have downloaded and compiled PHP 7.4.4 along with XDebug 2.9.3. On the Windows side, I have installed PHPStorm.
So the idea is to write PHP code in PHPStorm on Windows and run and debug PHP code on Ubuntu over WSL2. To do that, we need to setup remote debugging for XDebug so that PHPStorm can connect to it and set breakpoints, show variable values and step through the code. I’m going to steal this Gif from XDebug website to show you how this is going to work, understanding this architecture helps you with debugging if you run into an issue during this step:
There is also an option to have XDebug identify the IP address of our IDE through the initial HTTP request (xdebug.remote_connect_back) but unfortunately it does not work under our current setup. I did not get into debugging why that does not work. You can take a look at the packets being transmitted in Wireshark and see what goes wrong. I suspect because both of the machines are running on the same network and some weird translations are being performed by WSL2, maybe the Ubuntu sees Windows host packets as if they are coming from 127.0.0.1. So this is what XDebug configuration looks like inside our php.ini file. You will need to modify the zend_extension path to point to your installation of XDebug. You can also uncomment the last line and create the path to the log file if you need to debug this further:
[xdebug]
zend_extension="/usr/local/lib/php/extensions/no-debug-non-zts-20190902/xdebug.so"
xdebug.remote_enable = 1
xdebug.remote_port = 9000
# xdebug.remote_log=/var/log/xdebug/xdebug.log
First, we configure PHPStorm to use XDebug. Under File>Settings>Languages & Frameworks > PHP:
Notice how we need to give Windows IP address to XDebug so that it can connect back to PHPStorm. The thing with WSL2, at least in its current form is that the IP range will totally change during reboots. Let’s say the IP range of the network of WSL2 is currently in the range of “172.30.0.1″, the next time you reboot the machine, and its gonna happen with a Windows machine, the IP address will be in the range of “172.16.14.1”. So we need a way to identify this IP address after each reboot. Ideally, a dynamic entry in hosts file that will map “wsl2.host” to this IP address. This way, we don’t have to update our PHPStorm configuration with the correct IP address every time.
My solution is to run a .Net Core application after each reboot. This small application will read the new IP address of Windows WSL2 interface and update the hosts file entry accordingly. The source code is available here: https://github.com/silverfoxy/wsl2_host_ip.
Download the release build of this program. Put it under “Program Files”, and create task under Windows Task Scheduler to run this program with elevated privileges (To update the hosts file) after each login and the action is to run a program which points to our executable.
Now this will add an entry to the Windows hosts file named “wsl2.host“. Recall that we used this host name earlier in our PHPStorm configuration that is passed through the command line to XDebug so that it can connect back from WSL2 Linux VM to our Windows host machine.
This way, we can use our setup and develop PHP applications on Windows while debugging them against the latest version of PHP on Linux. You can verify this by setting a breakpoint in PHPStorm and the breakpoint should pause the execution. Yaaaay!!
There is also an easier way to do this which I briefly introduce. The idea is to use X11 forwarding, install everything (PHP, XDebug, PHPStorm) on Linux and just use the UI on Windows. This also works well, and was not perceivably slower. It feels like the fonts are rendered slightly pixely, but I’m not sure if this is truly the case or just a bias between Windows and Ubuntu fonts for PHPStorm. But after all this is an easier setup. I used VcXsrv for X11 forwarding on Windows and it works well. You can follow this tutorial for this setup: https://medium.com/swlh/get-wsl2-working-on-windows-10-2ee84ef8ed43