This is not such a quick tip. This is about running an nginx server on local development setup without the use of fancy things like containers, docker, or ansible.
NOTE: Every mention of WSL refers to WSL 2 in this context. I started using windows after WSL 2 was released, so I have no idea about the features and limitations of WSL 1.
ANOTHER NOTE: This might look like a trivial problem to you but I am dumb and it took me this long essay to wrap my head around just stating the problem.
Here’s a TL;DR though
With a windows machine running WSL 2 (Ubuntu), I want to be able to access an http server running inside WSL 2 on any connected device on the same network, preferably with a static IP and the ability to give it a name that all devices can consistently use: something like a local dns for the devices on the local wifi network.
I am a web developer and it is essential for me to be able to run a web server on the computer and be able to access it across my local network on all connected devices.
Weirdly, it has been a constant pain to access web pages over http on connected devices on the local wifi – it doesn’t help much that I have to work on a locally created wifi hotspot and the features available on the router are terribly limited – I’ve had to read a lot of documentation perhaps meant for sys-admins in order to achieve this simple task on the windows computer which was never an issue when I was developing on my linux computer.
This time around, I thought I might as well document what I am doing so I don’t have to go on a googling spree next time windows update fucks up my setup.
The setup
NOTE: If you are by some weird twist of fate reading this post, please note that this does not take into consideration any production level security; this is all about quickly wrangling a development setup that works and gets out of the way.
After trying multiple things, I have finally settled on the following boundary conditions for the setup of my development environment (not into containers and all that yet, so I am going old-school).
-
If it is a nodejs app, I just rely on the server started by the node app, either the one started by express, or simply run the
http-serverpackage. It could be anything though, for example:hugo servestarts a server at localhost:1313 by default and it is accessible as such on the host machine. This is easily accessible on the computer within wsl and on the host windows computer via locahost:port combination. But I fancy myself a bit of pretty urls, so I decided to experiment with setting up nginx reverse proxy for this.Reason I wanted to try out proxy setup is because eventually I also want to deploy my nodejs applications to production on my own server and it is more than likely I will be setting that up myself for at least the first few iterations.
The reverse proxy in a nutshell:
- suppose we have a server in wsl running on, say,
localhost:1313 - we have an nginx virtualhost with
madeupservernamelistening on port 1313 - we have an entry in hosts file on the host machine for
madeupservernamepointing to the home loopback address - reverse proxy config for
madeupservernamethat makeshttp://localhost:1313available onhttp://madeupservernameon the host machine.
- suppose we have a server in wsl running on, say,
-
If it is just a bunch of static files or a website I am managing for myself, I have plenty of madeupservername’s for those with appropriate dev level config files for each for the nginx instance running in wsl2.
For example:
morjal.comis being hosted on local asmorjal-comthat is always available on the local machine (host).- Why though? Why not just use
localhost:xxxx/morjal.com/dist/instead ofhttp://morjal-com/ - Look again at the question. Yes, that is why. This is where you should drift off if that didn’t make sense. :)
The problem
So, what is the problem with this? None, so far, at least on the development box, we’re all set but when it comes to accessing this same url on my mobile device connected to the same wifi network, that’s a different story.
Here are the considerations:
- I want to run all http servers preferably within WSL2, unless it’s a temp thing fired up by some vscode extension running on the host windows machine, which should also be available to devices across the local network.
- I want to be able to have a hosts entry (or a dns entry) pointing to this dev machine on my local wifi network that allows access to this dev server to all devices on the local network.
I sense my frustration has lead to some annoying repetition there. I suppose it is abundantly clear now though. This is basic and I never needed to wrestle with system configurations to achieve this.
Problem statement
-
Browsers and applications running on host windows box should be able to access my madeupserername over http. DONE, this works with an entry in hosts file on windows pointing to 127.0.0.1
-
Browsers on connected devices on the network should be able to access the files over http through the IP of the windows host machine (or distro running in WSL 2, i don’t care as long as I can set it to some static addr).
-
Browsers running on connected devices should be able to access this local IP via some local DNS – aah, that’s the one I have never done before.
Unfortunately, I am not running any local dns and making new entries into hosts file on every device is a viable alternative (i don’t have many devices) but ideally I’d want to have a single dns thing able to serve all devices on the local network. I don’t know why this has been eluding me all this while but I haven’t been able to make this setup for my dev environment yet.
If the connected devices on the same network, mostly android phone, or a tablet, or
another computer running a different OS or test browser, could access the IP of
this server running inside WSL2, the next problem I have is to be able to point
to that IP on those non-rooted android devices because I am unable to edit the
hosts file on those systems.
But currently, I am totally unable to access this machine running WSL2 via it’s IP over http from any connected device on the same network.
Helpful links
-
This is the exact problem I am facing.
There is a single answer to this post that suggests an npm package.
-
https://stackoverflow.com/a/66485783/699556
From this I learned that any requests to localhost are forwarded to WSL by default. This is probably how it works on the host machine out of the box without setup.
-
https://www.youtube.com/watch?v=yCK3easuYm4
David Bombal talks about WSL 2 networking in this video which may help with this matter if I could grok what is being said.
This one, however, brings up another problem I haven’t sorted yet on this computer. It talks about connecting to the virtual machine running in wsl via windows Remote Desktop Connection which is again, not working out of the box for me. Maybe that’s because I haven’t enabled some remote access to this ubuntu machine or I am just running a headless ubuntu and it won’t connect via remote desktop, I don’t know. shrug