lando / lando

A development tool for all your projects that is fast, easy, powerful and liberating
https://lando.dev
GNU General Public License v3.0
4.09k stars 545 forks source link

[Solved] xdebug no longer working when using WSL2 #2271

Closed web-assistant closed 4 years ago

web-assistant commented 4 years ago

Xdebug was working with my Lando setup with PhpStorm. I have since started using WSL 2 and xdebug no longer triggers. I haven't changed any settings in PhpStorm or any other Lando settings. Any ideas?

System specs:

$ lando version
v3.0.3
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.1 LTS
Release:        18.04
Codename:       bionic
$ uname -a
Linux Rusty 4.19.84-microsoft-standard #1 SMP Wed Nov 13 11:44:37 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
$ docker -v
Docker version 19.03.8, build afacb8b7f0
$ docker-compose -v
docker-compose -v
docker-compose version 1.25.5, build 8a1c60f6

.lando.yml

name: mysite
recipe: drupal7
config:
  php: '7.2'
  via: apache
  webroot: web
  database: mariadb
  drush: ^8
  xdebug: false
  config:
    php: .lando/.lando.php.ini
    database: .lando/.lando.mysql.cnf

proxy:
  appserver:
    - mysite.lndo.site
    - www.mysite.lndo.site
  mailhog:
    - mail.mysite.lndo.site
  pma:
    - pma.mysite.lndo.site
  adminer:
    - adminer.mysite.lndo.site

services:
  database:
    creds:
      database: mysite
      user: webassistant
      password: root
  appserver:
    overrides:
      environment:
        # Support debugging Drush with XDEBUG.
        PHP_IDE_CONFIG: "serverName=appserver"
  mailhog:
    type: mailhog
    hogfrom:
      - appserver
    portforward: true
  pma:
    type: phpmyadmin
    hosts:
      - database
  adminer:
    type: compose
    services:
      image: dehy/adminer
      command: /bin/s6-svscan /etc/services.d
    portforward: true

tooling:
  xon:
    service: appserver
    description: Enable xdebug for apache.
    cmd: "docker-php-ext-enable xdebug && /etc/init.d/apache2 reload"
    user: root
  xoff:
    service: appserver
    description: Disable xdebug for apache.
    cmd: "rm /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini && /etc/init.d/apache2 reload"
    user: root

excludes:
  - .idea
  - .git

.lando.php.ini

[PHP]

;;;;;;;;;;;;;;;
; PHP Globals ;
;;;;;;;;;;;;;;;

short_open_tag = Off
output_buffering = 4096
allow_call_time_pass_reference = Off
request_order = "GP"
register_long_arrays = Off
register_argc_argv = Off
magic_quotes_gpc = Off
enable_dl = Off
allow_url_fopen = On
realpath_cache_size = "800K"
realpath_cache_ttl = "86400"
disable_functions =
sendmail_path=/bin/true
;include_path = ".:/usr/share/pear:/usr/share/php"

[Date]
date.timezone = "UTC"

;;;;;;;;;;;;;;;;;;;;;;
;; PACKAGE SETTINGS ;;
;;;;;;;;;;;;;;;;;;;;;;

; Xdebug
xdebug.max_nesting_level = 512
xdebug.show_exception_trace = 0
xdebug.collect_params = 0
xdebug.remote_port = 9002
xdebug.idekey = PHPSTORM
xdebug.remote_enable = 1
;xdebug.remote_autostart = 1
xdebug.remote_log = /app/.lando/xdebug.log

; Globals
expose_php = on
max_execution_time = 90
max_input_time = 900
max_input_vars = 10000
memory_limit = ${PHP_MEMORY_LIMIT}
upload_max_filesize = 200M
post_max_size = 200M
error_reporting = E_ALL & ~E_DEPRECATED
ignore_repeated_errors = on
html_errors = off
display_errors = on
log_errors = on
max_execution_time = 5000
max_input_time = 5000
memory_limit = 1000M
post_max_size = 750M
upload_max_filesize = 750M
pirog commented 4 years ago

@web-assistant we dont officially support WSL so not surprising

web-assistant commented 4 years ago

Oh! That's a shame because it all seems to work apart from xdebug.

I should have found that out before spending time to get it working 🤦‍♂️

pirog commented 4 years ago

@web-assistant i know that there are people who use Lando on WSL2 successfully, we just don't support that use case currently

ayalon commented 4 years ago

The issue is the network configuration. Lando sets the xdebug.remote_host to the IP of your WSL Container. But PHPStorm is not listiening on this address.

For example, the xdebug.remote_host ist set to $LANDO_HOST_IP. This IP changes after every reboot, which makes it even harder.

Example: xdebug.remote_host=172.19.16.103

My Windows host, where PHPStorm is running has a different IP: 172.19.16.1 This is where PHPStorm is listening on Port 9000.

In the xdebug.los i see:

[1427] Log opened at 2020-07-23 17:41:28
[1427] I: Connecting to configured address/port: 172.19.16.103:9000.
[1427] E: Time-out connecting to client (Waited: 200 ms). :-(
[1427] Log closed at 2020-07-23 17:41:28

I tried to override the xdebug.remote_host to xdebug.remote_host=172.19.16.1 but from within the container I also was not able to connect to this IP.

[559] Log opened at 2020-07-23 14:28:59
[559] I: Connecting to configured address/port: 172.19.16.1:9000.
[559] E: Time-out connecting to client (Waited: 200 ms). :-(
[559] Log closed at 2020-07-23 14:28:59

Maybe a lando maintainer can give us a hint, how we can route the xdebug request from within the appserver container to the Windows host.

ayalon commented 4 years ago

From within WSL2 command line, I can connect to PHPStorm: nc -w5 -z -v 172.19.16.1 9000 Connection to 172.19.16.1 9000 port [tcp/*] succeeded!

I installed a few debug tools in the container: lando ssh --service appserver --user root --command "apt-get update && apt install net-tools traceroute netcat iputils-ping-y"

But inside the container, there is no route the the host ip and I have no clue how to set up one.

nc -w5 -z -v 172.19.16.1 9000
172.19.16.1: inverse host lookup failed: No address associated with name
(UNKNOWN) [172.19.16.1] 9000 (?) : No route to host
ayalon commented 4 years ago

I'm quite close now. I can determine the Windows Host IP and save it to an enviroment variable using: WSLIP=$(grep nameserver /etc/resolv.conf | cut -d ' ' -f2)

But I cannot fiiure out, how to route from inside the lando docker container to this IP.

Any ideas are highly welcome.

ayalon commented 4 years ago

After long journey I finally got it working. It's easier than expected. My PHPStorm is running on the Windows host. Files are synced back from the container to NFS using mutagen.io.

After debugging and testing, I found out, that the ENV variable $LANDO_HOST_IP is set to the WSL2 Distro IP (run ifconfig). All I had to do was the following change in the .lando.yml

  appserver:
    xdebug: true
    overrides:
      environment:
        # support debugging Drush with XDEBUG.
        PHP_IDE_CONFIG: "serverName=appserver"
        LANDO_HOST_IP: "host.docker.internal"
        XDEBUG_CONFIG: "remote_enable=1 remote_host=host.docker.internal"

Changing only LANDO_HOST_IP did not work but overriding XDEBUG_CONFIG with the correct remote_host works.

Hurray!

web-assistant commented 4 years ago

@ayalon You're a star, this works for me 👍

I can finally use W2L2 🥳

jnfDev commented 4 years ago

After a time, this stops working for me 😢 I need help.

After long journey I finally got it working. It's easier than expected. My PHPStorm is running on the Windows host. Files are synced back from the container to NFS using mutagen.io.

After debugging and testing, I found out, that the ENV variable $LANDO_HOST_IP is set to the WSL2 Distro IP (run ifconfig). All I had to do was the following change in the .lando.yml

  appserver:
    xdebug: true
    overrides:
      environment:
        # support debugging Drush with XDEBUG.
        PHP_IDE_CONFIG: "serverName=appserver"
        LANDO_HOST_IP: "host.docker.internal"
        XDEBUG_CONFIG: "remote_enable=1 remote_host=host.docker.internal"

Changing only LANDO_HOST_IP did not work but overriding XDEBUG_CONFIG with the correct remote_host works.

Hurray!

chosten commented 3 years ago

Just setting remote_host=host.docker.internal instead of xdebug.remote_host = ${LANDO_HOST_IP} worked for me.

jnfDev commented 3 years ago

Anything works for me :/ I have this configuration right now, I anyone can help me, I would be very grateful.

.lando.yml

name: themekraft-premium
recipe: wordpress
config:
  webroot: .
  xdebug: true
services:
  appserver:
    overrides:
      environment:
        PHP_IDE_CONFIG: "serverName=appserver"
        LANDO_HOST_IP: "host.docker.internal"

php.ini (.vscode/php.ini)

; Xdebug
xdebug.max_nesting_level = 256
xdebug.show_exception_trace = 0
xdebug.collect_params = 0
; Extra custom Xdebug setting for debug to work in VSCode.
xdebug.remote_enable = 1
xdebug.remote_autostart = 1
xdebug.remote_host = host.docker.internal
; xdebug.remote_connect_back = 1
xdebug.remote_log = /tmp/xdebug.log
jnfDev commented 3 years ago

I was able to fix my issue changing host.docker.internal by ${WSL_IP}, where ${WSL_IP} is an environment variable created by me: export WSL_IP=$(hostname -I)

The final Lando config file ended up like this:

name: tk-free
recipe: wordpress
services:
  appserver:
    webroot: .
    xdebug: true
    overrides:
        environment:
          LANDO_HOST_IP: ${WSL_IP}
          XDEBUG_CONFIG: remote_autostart=1 remote_enable=1 remote_host=${WSL_IP}

I don't know if this is the best solution but works for me. 😊✌

tanc commented 3 years ago

@jnfDev thank you, yours is the only solution that worked for me. I have a WSL2 set up running Ubuntu and Docker inside the WSL2 environment (not using Docker for Windows). In Linux's docker version host.docker.internal does not exist (see https://github.com/docker/for-linux/issues/264). I should also note these settings are for xdebug version 3 which is now the default in Lando.

export WSL_IP=$(hostname -I) outputs a lot of IP addresses for me so I need:

export WSL_IP=`hostname -I | awk '{print $1}'`

This can be set in .bashrc or similar.

My .lando.local.yml (lando override for my environment) looks like this, with the most minimal settings required to get xdebug working with my set up:

services:
  appserver:
    xdebug: debug
    overrides:
      environment:
        XDEBUG_CONFIG: client_host=${WSL_IP}

xdebug: true or xdebug: debug (they are the same) is needed to enable xdebug's debug mode.

Annoyingly the start_with_request can't be set with an environment variable so that needs to also be set in a custom php.ini

This would look something like this:

[PHP]

; Xdebug
xdebug.start_with_request = yes

See the docs for how to include.

Edit: noted xdebug version 3 and added php.ini required.

Tigatok commented 3 years ago

Hi all,

I ended up going to war over this, for quite a while. I am not sure how everyone else's was working out of the box. I finally got everything to work, with lando, xdebug3 and WSL2, with PHPStorm running inside the WSL2 container. Here is my setup:

I followed pretty much all the instructions from this thread, and many others out there. I was still receiving the classic timed out with ip commands for Xdebug.

I played around with netstat -nl --protocol=inet,inet6 and noticed that my 9003,9000 ports were listening on :::: which is not ipv4 (I think?).

So I then went into PHPstorm's Help -> Edit Custom VM Options, and added the following: -Djava.net.preferIPv6Addresses=false -Djava.net.preferIPv4Stack=true

This then changed phpstorm to listen on the same IPv4 networks the other things were running on.

My lando file was updated to add this for the config/services:

config:
  php: '7.3'
  via: nginx
  webroot: web
  xdebug: off
  config:
    php: .lando/php.ini
services:
  appserver:
    overrides:
      environment:
        DRUSH_OPTIONS_URI: https://mysite.lndo.site
        XDEBUG_MODE:
        LANDO_HOST_IP: host.docker.internal

I added this tooling:

  xdebug:
    description: Loads Xdebug in the selected mode.
    cmd:
      - appserver: /app/.lando/xdebug.sh
    user: root

Then, created 2 files xdebug.sh and php.ini located in a new folder I created .lando in root. Those files:

Xdebug.sh

#!/bin/bash

if [ "$#" -ne 1 ]; then
  echo "Xdebug has been turned off, please use the following syntax: 'lando xdebug <mode>'."
  echo "Valid modes: https://xdebug.org/docs/all_settings#mode."
  echo xdebug.mode = off > /usr/local/etc/php/conf.d/zzz-lando-xdebug.ini
  pkill -o -USR2 php-fpm
else
  mode="$1"
  echo xdebug.mode = "$mode" > /usr/local/etc/php/conf.d/zzz-lando-xdebug.ini
  pkill -o -USR2 php-fpm
  echo "Xdebug is loaded in "$mode" mode."
fi

php.ini

xdebug.client_port = 9003
xdebug.log = /tmp/xdebug.log
xdebug.client_host = host.docker.internal

Finally, I restarted all my systems, and then once lando is up and running: lando xdebug debug and this should turn debugging on.

With this I can now use phpstorm inside the WSL container, and use a browser from my host to trigger the debug.

I am interested if anyone can help me understand more about why I had to do these steps, and I never saw anyone recommend similar either.

I did NOT Create a wslbridge in windows, and most of what I am using right now is stock WSL2 (I did this from a fresh windows 10 install).

Tks.

Edit 1: Without setting the new xdebug.start_with_request=yes in the php.ini file, you should have a browser extension that sets the proper flags to get picked up by the IDE.

Tigatok commented 3 years ago

Update,

I don't know what exactly happened, however I lost my ability to xdebug. I had to then look and add a specific rule for Xdebug in my windows firewall. The weird thing was, that I had to specify the TCP port of 9000 on windows, even though my xdebug 3 is running on 9003 and is the only listening port on my wsl2 container... Interested in finding out more.

mrtronje commented 3 years ago

@Tigatok could you post your firewall rule and IDE (phpstorm?) settings?

ayalon commented 3 years ago

I have a different findings. Please use the PHP Option xdebug.discover_client_host = 0 to disable the that the client_host is overriden. I figured it our when checking the settings in phpinfo().

here is my php.ini included in lando:

xdebug.max_nesting_level = 256
xdebug.show_exception_trace = 0
xdebug.client_host = host.docker.internal
xdebug.log = /tmp/xdebug.log
xdebug.mode = debug
xdebug.start_with_request = yes
# Without this option, the client_host will be overriden.
xdebug.discover_client_host = 0
error_log = /tmp/error.log
ayalon commented 3 years ago

If the client_host is set to host.docker.internal you will need no firewall rule.

drennvinn commented 3 years ago

I solved this problem by changing the IP address of xdebug.client_host (in my case, Xdebug ^3.0) and I wrote this little script to refresh the host after each reboot.

#!/bin/bash

PHP_VERSION=$(php -r "echo PHP_VERSION;" | grep --only-matching --perl-regexp "\d+.\d+")

# Get the value of xdebug.client_host in xdebug.ini
OLD_IP=$(awk -F "=" '/xdebug.client_host/ {print $2}' /etc/php/$PHP_VERSION/mods-available/xdebug.ini)

# Get the new IP address (in case you have restarted the computer)
NEW_IP=$(awk '/nameserver/ {print $2}' /etc/resolv.conf)

echo "Current IP address :  " $OLD_IP
echo "New IP address :  " $NEW_IP

# Replace old IP by the new and restart php (in my case php-fpm)
sudo sed -i /etc/php/$PHP_VERSION/mods-available/xdebug.ini -e 's/'$OLD_IP'/'$NEW_IP'/g' && sudo service php$PHP_VERSION-fpm restart
IQ-JYe commented 3 years ago

None of these are working for me. Strange thing is that it was working a few days ago and then stopped working for no reason. xdebug.log says: [1649] [Step Debug] INFO: Connecting to configured address/port: host.docker.internal:9003. [1649] [Step Debug] WARN: Creating socket for 'host.docker.internal:9003', poll success, but error: Operation now in progress (29). [1649] [Step Debug] ERR: Could not connect to debugging client. Tried: host.docker.internal:9003 (through xdebug.client_host/xdebug.client_port) :-( [1649] [Step Debug] INFO: Connecting to configured address/port: host.docker.internal:9003.

gatsby0121 commented 3 years ago

Just to add something I had to do in order to get this to work.

Windows 10 WSL2 Ubuntu 20.04 Lando installed in Ubuntu Docker Desktop running from windows

I ran this from powershell:

$remoteip = wsl.exe /bin/bash -c "ip addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'"
netsh interface portproxy add v4tov4 listenport=9003 listenaddress=0.0.0.0 connectport=9003 connectaddress=$remoteip

After that, everything started to work

cicadabear commented 3 years ago

If someone doesn't want to hardcode or modify their docker, Dockerfile, or compose file (maybe someone is using a 2.x xdebug, it doesn't support environment variable). Adding the header X-Forwarded-For by using a header modifying extension on the browser so as to set $_SERVER['HTTP_X_FORWARDED_FOR'] is a very convenient approach. Don't forget the configuration xdebug.remote_connect_back=1.

Dockerfile

FROM  php:7.1-apache

RUN yes | pecl install xdebug-2.5.5 \
    && echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini \
    && echo "xdebug.remote_port=9000" >> /usr/local/etc/php/conf.d/xdebug.ini \
    && echo "xdebug.remote_enable=1" >> /usr/local/etc/php/conf.d/xdebug.ini \
    && echo "xdebug.remote_connect_back=1" >> /usr/local/etc/php/conf.d/xdebug.ini \
    && echo "xdebug.remote_log=/tmp/xdebug.log" >> /usr/local/etc/php/conf.d/xdebug.ini \
    && echo "xdebug.remote_autostart=off" >> /usr/local/etc/php/conf.d/xdebug.ini

ModHeader extension Xdebug helper

xdebug.log

Log opened at 2021-07-06 16:06:59
I: Checking remote connect back address.
I: Checking header 'HTTP_X_FORWARDED_FOR'.
I: Checking header 'REMOTE_ADDR'.
I: Remote address found, connecting to 172.17.0.1:9000.
W: Creating socket for '172.17.0.1:9000', poll success, but error: Operation now in progress (29).
E: Could not connect to client. :-(
Log closed at 2021-07-06 16:06:59

Log opened at 2021-07-06 16:07:40
I: Checking remote connect back address.
I: Checking header 'HTTP_X_FORWARDED_FOR'.
I: Remote address found, connecting to 172.30.112.1:9000.
I: Connected to client. :-)
no-sssweat commented 2 years ago

For me my xdbug 3 used to work fine, but broke inexplicably many months ago. It has been a frustrating process to fix it, as I tried every config under the sun, but I finally found the fix.

.lando.php.ini

; Xdebug
xdebug.max_nesting_level = 256
xdebug.show_exception_trace = 0
xdebug.client_host = ${LANDO_HOST_IP}
xdebug.log = /tmp/xdebug.log
xdebug.mode = debug
xdebug.client_port = 9003
xdebug.start_with_request = yes

.lando.info.yml

name: d9
recipe: drupal9
config:
  webroot: web
services:
  appserver:
    type: php
    xdebug: true
    config:
      php: .lando.php.ini
    overrides:
      environment:
        PHP_IDE_CONFIG: "serverName=appserver"
        LANDO_HOST_IP: "host.docker.internal"
        XDEBUG_CONFIG: "remote_enable=1 remote_host=host.docker.internal"

However, in PHPStorm (IDE), I noticed when I clicked the start listening icon, at bottom right corner there was this message.

image

Running Command Promp as administrator

netstat -a -n -o | find "9003"

I was able to get the ID of the program that was using that port.

image

Then on windows task manager, in the details tab, I was able to find the program that was using that ID

image

and ending the task, fixes the issue as port 9003 is freed up. Now I'm able to connect and use xdbug as expected.

In case you wonder, I did try to change the port to another like 9005 in .lando.php.ini and on my PHPStorm IDE settings, but xdebug did not work for whatever reason.