Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ray on WSL2 #191

Closed
freekmurze opened this issue Jan 18, 2021 · 32 comments
Closed

Ray on WSL2 #191

freekmurze opened this issue Jan 18, 2021 · 32 comments

Comments

@freekmurze
Copy link
Member

Several users have reported troubles getting Ray to work on WSL2. Example: spatie/laravel-ray#107

I'm guessing that one would need to somehow map the port 23517 between the WSL2 environment (where the PHP projects sends message to) and 23517 locally (where the Ray app is running). Unfortunatel, I don't have any experience with this.

I would appreciate anyone that has got this to work, adds the steps needed as a new section on this page (there's an edit button on top): https://spatie.be/docs/ray/v1/environment-specific-configuration/windows-10

@axelitus
Copy link
Contributor

Solving this issue is easier than you might think. It's arguably the same as any dockerized app.

First a bit of background about how WSL2 works:
Linux in Windows on its second iteration (WSL2) it's nothing more than an optimized VM running a full Linux OS. It has some kernel changes and integration procedures to make it easier to have a "seamless" integration with Windows, though it, being a VM has its, quirks and downsides.

Although for most things you can get away with referencing localhost from Windows and let Linux respond (my website is running on Linux WSL2 and I open a browser in Windows and navigate to localhost and I get the page (because ports are forwarded from Windows to Linux) it does not work the other way around. If you reference localhost from within Linux on WSL2, you are referencing the VM, not your Windows host.

So, knowing this, the Ray app is running on Windows, but your code is executing in WSL2, so to get around with this setup, you need to reference your Windows host. This would be so easy if Hyper-V machine networks were easier to configure, but as it stands today it is not so. So each time you boot up your WSL2 Linux, it gets a new IP address. Even further, you get an IP address from a random internal segment, so it is a bit harder to get by with this. So what I've done is to assign my Windows host a fixed IP address (this can be done on ethernet by specifying an IP directly in the network adapter or by reserving an IP address in your DHCP server).

In your ray.php config file (or if you are using laravel-ray in the .env file) you set your RAY_HOST value to the IP address that your Windows host is assigned to in the network adapter. (WSL2 will automatically add the routing needed to reach the LAN segment from within WSL2).

With a more precise configuration example it would look like so:
Windows host IP address: 192.168.5.21
WSL2 host IP address (WSL segment): 172.27.238.76

You should put your RAY_HOST value to 192.168.5.21 and everything should work fine:
image

If you are using PhpStorm or the like to debug you would get similar issues because essentially your Windows 10 host and the WSL2 VM are two separate devices.

If you need further advise don't hesitate to let me know.

@axelitus
Copy link
Contributor

By the way, I've tested this using Laravel Sail with Docker. Let me create a blank project and test it with a Command (it should work though). I'll document my findings here.

@mhluzi
Copy link

mhluzi commented Jan 19, 2021

@axelitus, thanks so much for this - works for me!

@axelitus
Copy link
Contributor

axelitus commented Jan 19, 2021

Glad I could help @mhluzi!

The only thing I'm not getting to work currently is the file link to open with PhpStorm:
image

I'm getting this Windows 10 unhelpful screen:
image

I'm not sure if it's related to paths in WSL2 (using RAY_LOCAL_PATH and RAY_REMOTE_PATH to do the mapping).

@mhluzi
Copy link

mhluzi commented Jan 19, 2021

In case it helps anyone my paths are:

'remote_path' => env('RAY_REMOTE_PATH', '/home/ubuntu2004/mysite'),
'local_path' => env('RAY_LOCAL_PATH', '\\wsl$\Ubuntu-20.04\home\ubuntu2004\mysite'),

I am using VSCode and it opens the link as expected.

@qwertynik
Copy link

@axelitus
Facing the same issue. Not sure about the steps that would help in opening PHPStorm when clicking on the link.
Will post a solution here when I find one. Can you as well post the solution when you find one?

@oliverhermanni
Copy link
Contributor

@qwertynik @axelitus There already is a solution in the docs for that, look here.

@qwertynik
Copy link

Sure @oliverhermanni will check. Thanks!

@freekmurze
Copy link
Member Author

@axelitus Nice!

Could you PR a summary of #191 (comment) to this page in our docs?
https://spatie.be/docs/ray/v1/environment-specific-configuration/windows-10
There's an edit button on top.

I'm pretty sure this will be helpful for a lot of people.

@freekmurze
Copy link
Member Author

Closing this as the issue is resolved.

@axelitus
Copy link
Contributor

@oliverhermanni thanks for the link! Yesterday was already late and today you have fixed my issue 😃

@freekmurze sure, I'll send a PR to the docs!

@FullWebService
Copy link

FullWebService commented Jan 22, 2021

When I put my local_path as such:
'local_path' => env('RAY_LOCAL_PATH', '\\\\wsl$\\Ubuntu\\home\\spatie\\code\\my-project'),

Ray doesn't add the file where it's called to the link. I've added a Ray call in web.php on line 17 and it sends me to \\wsl$\Ubuntu\home\spatie\code\my-project:17

I'm using WSL2 with Laravel Sail. The rest worked out of the box!

Anyone else with this problem?

@mdpoulter
Copy link

mdpoulter commented Jan 22, 2021

@FullWebService Just had the same problem when using Laravel Sail on WSL2, but worked out that you need to set the paths as such:

'remote_path' => env('RAY_REMOTE_PATH', '/var/www/html'),

'local_path' => env('RAY_LOCAL_PATH', '\\\\wsl$\\Ubuntu\\home\\mdpoulter\\code\\example-app'),

@FullWebService
Copy link

@mdpoulter The /var/www/html worked. Sadly after \\wsl$\Ubuntu\home\mdpoulter\code\example-app it uses the Linux style path, so it becomes \\wsl$\Ubuntu\home\mdpoulter\code\example-app/routes/web.php which Windows won't open.

@mdpoulter
Copy link

mdpoulter commented Jan 22, 2021

@FullWebService Strange, it works for me even with the alternating path 🤔 Are you using PhpStorm? And if so, did you check out the first section of this page in the docs?

@FullWebService
Copy link

@mdpoulter No I'm using VSCode. The weird thing is, the slashes don't seem to be the problem. Windows seems to remove the first slash for some reason, so it becomes \wsl$\Ubuntu\home... The double slash is visible in Ray when I hover over the link, though. I've tried adding more slashes in my local path, but then it just won't open.

Weird.

@mdpoulter
Copy link

@FullWebService If you've got the 4 slashes at the beginning of your RAY_LOCAL_PATH then I'm out of ideas unfortunately 🙈 Perhaps one of the others on the thread will be able to assist.

@FullWebService
Copy link

@mdpoulter Yeah, all four are there! Figured out that Linux style slashes also work in the local path, but then the first slash also gets removed. Thanks for your help! Currently digging through the VSCode issues if there's something that might help.

@axelitus
Copy link
Contributor

axelitus commented Jan 22, 2021

I'm not sure how the path is built in Ray app, it would be nice that it uses the OS path separator instead of fixed /, though this is just "cosmetic" as the path is still understood by Windows.

Unfortunately, apps (Sublime Text and PhpStorm at least) do not register a protocol handler in Windows, thus the entry about PhpStorm (haven't found a solution for Sublime Text yet).

VSCode seems to register a protocol handler, and as you said it seems to be receiving the path without the first slash:
image

but I don't know if this is a Ray issue or the way the protocol handler sends the path to the actual application (I think is the latter, and it would be better to report it as an issue here unless @freekmurze identifies that it's a problem with Ray.

@axelitus
Copy link
Contributor

axelitus commented Jan 23, 2021

I have been digging deeper into this and it seems that the VSCode protocol is not being sent correctly.

I've tapped into the protocol handler and this is the URL that Ray is sending in each case:

Sublime Text:
subl://open/?url=file://%5C%5Cwsl%24%5CUbuntu%5Chome%5Caxel%5Ccode%5Caxelitus%5Caxel.pardemann.me%2Fapp%2FHttp%2FControllers%2FWelcomeController.php&line=11

PhpStorm:
phpstorm://open/?file=%5C%5Cwsl%24%5CUbuntu%5Chome%5Caxel%5Ccode%5Caxelitus%5Caxel.pardemann.me%2Fapp%2FHttp%2FControllers%2FWelcomeController.php&line=11

VSCode:
vscode://file/%5C%5Cwsl%24%5CUbuntu%5Chome%5Caxel%5Ccode%5Caxelitus%5Caxel.pardemann.me%2Fapp%2FHttp%2FControllers%2FWelcomeController.php:11

To me, the VSCode URL seems malformed, it should resemble the other two, thus I think it should be:
vscode://open/?url=file://%5C%5Cwsl%24%5CUbuntu%5Chome%5Caxel%5Ccode%5Caxelitus%5Caxel.pardemann.me%2Fapp%2FHttp%2FControllers%2FWelcomeController.php:11

Can you confirm this @freekmurze?

UPDATE:
actually the URL is fine according to this: https://code.visualstudio.com/docs/editor/command-line#_opening-vs-code-with-urls

So I don't know why it is not working correctly.

@axelitus
Copy link
Contributor

By the way, if anyone is interested I've got a Sublime Text protocol handler working here: https://github.com/axelitus/windows10-editor-protocol-handler, want to add a PhpStorm version so I can have both into one package, work in progress.

@FullWebService
Copy link

I made a simple html link to the file it should link to:
<a href="vscode://file//wsl$/Ubuntu/home/me/project/routes/web.php:18">Go to VSCode</a>
This works. I think Ray is just missing a slash in the url. @freekmurze Can you check this, please?

@ukjadoon
Copy link

Just so that everyone here knows, here is how to fetch the IP address of the Windows host machine from WSL2:

In the terminal from within WSL2, run the following command,
ip route | grep default

This will give you the IP address that you can copy over to RAY_HOST in your .env file.

The next step is to allow WSL2 to connect to its host machine. This can be done by opening PowerShell but make sure that you open PowerShell as Administrator.

Run the following command,

New-NetFirewallRule -DisplayName "WSL" -Direction Inbound -InterfaceAlias "vEthernet (WSL)" -Action Allow

You can test if it is working by running ping $ip_address_you_discovered_earlier from within the WSL2 terminal to see if it is working properly. I hope it helps.

@axelitus
Copy link
Contributor

That is correct @ukjadoon but I don't recommend going this route because the WSL2 IP address changes on each reboot (not only the IP address but the IP segment that WSL uses). Read the updated WSL2 docs paged: https://spatie.be/docs/ray/v1/environment-specific-configuration/windows-10

Thanks for the powershell command! This works when Windows Firewall is the active firewall though, many antiviruses have their own Firewall that takes control instead of Windows Firewall, so look out for it.

@axelitus
Copy link
Contributor

@FullWebService if this is still an issue I would recommend you to open another issue as it seems to me the problem is diverting from the original issue.

@RhysLees
Copy link

RhysLees commented Dec 1, 2021

My solution was to add this into my .bashrc file it creates a new etc/hosts entry in WSL2 named winhost.
It will change the IP when the IP is changed after restarting WSL2
I'm not sure of security risks but it works fine for me

use winhost instead of localhost in .env

# Set winhost to wondows ip
export winhost=$(cat /etc/resolv.conf | grep nameserver | awk '{ print $2 }')
old_winhost=$(grep -P "[[:space:]]winhost" /etc/hosts | awk '{ print $1 }')

if [ -z $old_winhost ]; then
    echo "write winhost to /etc/hosts"
    echo "$winhost winhost" | sudo tee -a "/etc/hosts"
elif [ $old_winhost != $winhost ]; then
    echo "update winhost in /etc/hosts from $old_winhost to $winhost"
    sudo sed -i "s/$old_winhost winhost/$winhost winhost/g" /etc/hosts
fi

@nathan-io
Copy link

nathan-io commented May 30, 2022

I encountered this also, and resolved it with a modified version of @RhysLees solution (thanks for posting that) and the changes to my universal Ray config file (so I didn't have to specify any particular local_path).

I had to modify the command because I'm using Valet for Linux with WSL2, so my standard /etc/resolv.conf is replaced by Valet's configuration.

I changed the first line to:

export winhost=$(/mnt/c/Windows/System32/ipconfig.exe | grep -A 10 WSL | grep IPv4 | awk '{print $14; exit;}')

This provides the correct IP.

Then in my ray.php:

    'host' => env('RAY_HOST', 'winhost'),
    'remote_path' => env('RAY_REMOTE_PATH', '/var/www/html'),
    'local_path' => env('RAY_LOCAL_PATH', null),

Ray is now working fine on projects I accessed via WSL2 and Valet for Linux.

Unfortunately, this configuration doesn't work when I access the same project via Sail, though I tried different default values for RAY_HOST including "127.0.0.1" and "localhost".

@RhysLees
Copy link

I encountered this also, and a modified version of @RhysLees solution (thanks for posting that) in my universal Ray config file, so I didn't have to specify any particular local_path.

I had to modify the command because I'm using Valet for Linux with WSL2, so my standard /etc/resolv.conf is replaced by Valet's configuration.

I changed the first line to:

export winhost=$(/mnt/c/Windows/System32/ipconfig.exe | grep -A 10 WSL | grep IPv4 | awk '{print $14; exit;}')

This provides the correct IP.

Then in my ray.php:

    'host' => env('RAY_HOST', 'winhost'),
    'remote_path' => env('RAY_REMOTE_PATH', '/var/www/html'),
    'local_path' => env('RAY_LOCAL_PATH', null),

Ray is now working fine on projects I accessed via WSL2 and Valet for Linux.

Unfortunately, this configuration doesn't work when I access the same project via Sail, though I tried different default values for RAY_HOST including "127.0.0.1" and "localhost".

I am also using valet for Linux, does your modification stop you having to manually type the domain into Windows hosts file? Should have mentioned that I got the solution from somewhere else(can't remember where).

@nathan-io
Copy link

nathan-io commented May 30, 2022

does your modification stop you having to manually type the domain into Windows hosts file

I didn't have to edit the Windows hosts file, or Acrylic DNS hosts.

@RhysLees
Copy link

does your modification stop you having to manually type the domain into Windows hosts file

I didn't have to edit the Windows hosts file, or Acrylic DNS hosts.

Ah damb, I have to manually add the domains to Windows hosts files to access Valet served sites. Gonna look into that tomorrow. Thanks 😊

@nathan-io
Copy link

nathan-io commented May 31, 2022

It took some doing for me to get wildcard DNS working with Acrylic DNS, valet-linux, and WSL2. My solution was cobbled together from others.

One key for me was using chattr to make /etc/resolv.conf immutable, so WSL2 would stop overwriting the Valet config on each restart.

If you run into issues, I can post some of my notes.

@HassanZahirnia
Copy link

Anyone knows how to use Ray with the Windows host app when it's installed globally ? ( via global-ray )

The Ray Laravel package works fine when you call the ray function inside Laravel project php files. But if you want to use ray in a vendor file, or an open source project where they don't have ray installed it doesn't work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests