Using a docker proxy in WSL

I recently started working on a web-based project that has some non-standard networking stuff going on in the dev environment.  The fix was easy, but took a little searching, hence this post.

The codebase itself is built on Node JS, but I have to run it in WSL.  There are various build issues that keep it from building cleanly in Windows and it would be a bit of work to fix that.  But it builds just fine under WSL, so it's easier to use that.

The dev setup uses a Docker container running HAProxy.  It's set up to proxy the static portion of the website to the shared dev server (which is on the VPN) and direct the traffic for the dynamic part to a local port.  So we have a HAProxy running in Docker, the local dev server running in WSL, and the browser running in Windows.

The problem: In the default WSL config, this doesn't work.  The proxy to the shared server works just fine.  So if I go to wwwlocal.site.com, that works as a proxy to wwwdev.site.com.  Perfect!  However, wwwlocal.site.com/login is supposed to proxy to localhost:4321, but that results in a 503 error.  However, I can go directly to localhost:4321 and it works just fine, so this is clearly a networking issue.

The solution was to just add a few lines to my $home\.wslconfig file on Windows.  The following lines did the trick:

[wsl2]
networkingMode=mirrored
dnsTunneling=true
autoProxy=true

You can read more about these settings here.

The joy of WSL and desktop Linux

I had a workflow revelation on my work machine the other week: Corporate IT pushed a Windows 10 update that brought me up to a version that actually supports running Linux GUI apps under WSL!

I've WSL GUI apps on my home Win11 system for a while, but having that on my work machine is huge.  I use WSL extensively there.  See, we've been standardizing our dev environment setup using Lando, which is basically a convenience layer on top of docker-compose.  It's a handy tool, but the relevant thing to note here is that it works by directly mounting your project code directory inside the Docker container.  This is convenient for Mac and Linux users, but is kind of a problem for Windows users.

As you may (or may not) know, WSL2 is great and out-performs WSL1 in every way except one: cross-filesystem performance.  As long as you keep everything inside the WSL filesystem, you're golden and everything is fast.  But as soon as you try to cross from the Windows filesystem to the Linux one, or vice versa, performance just falls off a cliff.  Sure, it's not a big deal if you just want to edit a file or something like that, but anything that does any remotely significant amount of filesystem access (e.g. running an npm install) is just painful.  In my experience, it's not unheard of for the performance penalty to be on the order of 10x. 

Clearly that's not something you want to endure as part of your normal workflow.  The simple fix is to do all your work inside WSL, which for me means installing Lando in WSL and hosting my code inside WSL.  The only problem is managing the code.  If you want to do that in Windows, you need to do it over a network share, which works, but isn't exactly a great experience.  It also causes various permissions and file ownership issues for apps like Git that actually care about that.

That's where the WSL GUI apps come in.  Rather than dealing with the network share hassle, you can just install your favorite GUI tools inside WSL and run them just like you're on native Linux.  Problem solved!

Well, mostly solved.  Sadly, not everything runs on Linux.  In particular, there's no Linux port of SourceTree, which is currently my graphical Git client of choice.  But it's not that I particularly like SourceTree - it's just that I hate it less than all the other Git clients I've tried.  So I was forced to try some other options.

This part did not go well.  I tried a few different options, including GitFiend (which was nice, but would randomly crash under WSL) and Git-Cola, which was also decent, but which I had to drop because if left alone it would occasionally lock up and then somehow take down the entire system if I tried to close it.  I have no idea how it managed to do that (presumably some bug in WSL's GUI layer), but that's a different problem.  I also attempted to try Gittyup, but I couldn't, because it only offered Flatpak packages.  And, of course, the Flatpak daemon (or whatever it's called) won't install on WSL because it's missing some of the system-level stuff that it uses.  But that's a different post.

Eventually, I declared GUI bankruptcy and decided to actually learn how to use Fugitive, the Git plugin for Vim.  Turns out that Fugitive is actually pretty good and figuring it out was easier than finding a good graphical Git client.  But that's also a story for another post.

In any event, having WSL GUI apps is pretty nice.  Now I can do all my work in WSL, and still have both GVim and PHPStorm, if I need it, without having to pay the cross-OS performance price.  So I can have nice things and good performance.  Yay!

Installing PHPStorm under WSL2

The other week I tried to install PHPStorm under WSL2.  Because that's a thing you can do now (especially since Linux GUI apps now work in recent Windows 10 updates).  The installation process itself was pretty simple.

  • Download PHPStorm for Linux from JetBrains website.
  • Now extract the tarball and run the bin/phpstorm.sh script.
  • PHPStorm should start up.

The next step is to configure your license.  In my case, I was using a corporate license server.  The issue with this is that you need to log into JetBrains' website using a special link to activate the license.  Unfortunately:

  • By default, WSL doesn't have a browser installed.
  • Firefox can't be installed because the default build uses a snap image, and WSL apparently doesn't support snap.
  • PHPStorm doesn't appear to be able to properly deal with activating via a Windows browser (I tried pointing it to the Windows Chrome executable and got an error page that points to a port on localhost).

So how do we get around this?  Well, we need to install a browser in WSL and configure PHPStorm to use it.  So here's what we do:

  • Skip the registration for now by starting a trial license.
  • Download the Vivaldi for Linux DEB package from Vivaldi's website.  You could use a different browser, but I like Vivaldi and it offers a convenient DEB package, so I used that.
  • Install the Vivaldi DEB.  WSL will be missing some packages, so you have to run apt install --fix-broken after installing it.
  • Go into the PHPStorm settings and configure your web browsers to include Vivaldi and set it as the default browser.
  • Go back to the registration dialog and try again.  This time, PHPStorm should start up Vivaldi and direct you to the appropriate link.
  • Log into your JetBrains account and follow the instructions.  The web-based portion should succeed and registration should complete when you click "activate" in PHPStorm again.

There we go - PHPStorm is registered and works.  Mildly annoying setup, but not actually that bad.