Под катом небольшая заметка про то как можно настроить удобное окружение для работы с PHP, xdebug через Windows Subsystem For Linux 2 (WSL 2).
Для начала немного истории
Я очень долгое время жил в мире Ubuntu писать на PHP, NodeJS, GoLang сразу на той же системе, на которой все будет запускаться, крайне приятно. Но, к сожалению, наличие руководящей должности приводит к тому, что приходится пользоваться большим количеством софта, который работает только на Windows.
Очень долгое время я просто жил "через SSH". На моем ноутбуке просто стоял PhpStorm, в котором я через ssh правил файлы на Ubuntu сервере просто и работает.
Виртуалки сразу отбросил ноут не очень радовался соседям внутри:) Докер поджирал заметно ресурсы и без того перегруженного 100500 вкладками и копиями запущенных Phpstorm небольшой ноутбук dell e7390:) Докер крутится у нас в бою и как раз на дев серверах, куда я хожу через sftp.
Но прошло время и стало возможным легко и просто запустить у себя на винде WSL2 (http://personeltest.ru/away/habr.com/ru/news/t/516054) и я решил все же сделать удобное окружение для своей работы.
Теперь к делу
Базовая установка системы
Как установить WSL на Windows есть множество инструкций. Я все сделал по официальному мануалу с сайта Microsoft
После успешной установки в PowerShell нужно написать команду wsl и мы погружаемся внутрь Linux, который внутри Windows
Далее идет череда стандартных команд для настройки веб сервера на Ubuntu:
sudo apt updatesudo apt upgradesudo apt install apache2sudo apt install php libapache2-mod-php php-mysql php-xml php-curlsudo a2enmod rewrite
Все файлы моих проектов было доступы через
/mnt/d/work/projects/и_так_далее
. Да, я в курсе, что
стоит копировать файлы напрямую в файловую систему Linux, чтобы
работало быстрее. Но зачастую такого варианта по скорости
достаточно, но если чувствуете тормоза ФС, то стоит использовать
сетевой диск.
Теория гласит (да и здравый смысл тоже), что файлы, с которыми оперирует php должны быть в самой системе Linux, а не в виде подмонтированного NTFS винды. Если нужно чтобы файлы были полностью нативно в системе можно сделать следующее.
- Создать папку под WSL проект. Например
/home/user/projects
- Склонировать копию проекта туда же (уже внутренним GIT).
Например будет
/home/user/projects/test
- Подключить сетевой диск на директорию
\\wsl$\Ubuntu
где "Ubuntu" название вашего дистрибутива. Определить верное название можно путем перехода в папку\\wsl$
в проводнике - Добавляем папку в сетевом диске в PhpStorm
- Настроить маппинг директорий для отладки (чтобы шторм понимал
какому файлу соответствует файл, который прислал нам xdebug)
- Включить Automatic upload
- Теперь все изменения будут отправляться сразу же в WSL через сетевой диск и можно заниматься отладкой
Но в данном способе есть один неприятный минус надо синхронизировать файлы. Например вы перешли на другую ветку в винде = надо в линуксе тоже переходить в эту ветку. Двойная работа. Подумываю над каким нибудь хитрым скриптом, который с rsync будет все это делать сам, но пока не придумал. Если придумаете, пишите буду очень благодарен:)
Также не забывайте настройку Apache, чтобы он ходил в нужные директории. Если что, конечно, можно сделать связку из php-fpm и nginx тут уже на ваш вкус.
Настройка xdebug на сервере
Далее настраиваем xdebug стандартным путем по любому мануалу из интернета. Я опишу кратко порядок действий.
-
Устанавливаем xdebug через
sudo apt-get php-xdebug
-
Открываем
sudo nano /etc/php/7.2/mods-available/xdebug.ini
и приводим к такому содержимомуzend_extension=xdebug.soxdebug.remote_enable=truexdebug.remote_host=wsl.hostxdebug.remote_port=9002xdebug.profiler_enable=1xdebug.profiler_output_dir=/tmpxdebug.remote_autostart=onxdebug.idekey=PHPSTORMxdebug.remote_log=/tmp/xdebug.log
-
Перезапускаем apache
sudo service apache2 restart
Костыль для обратной связи
На этом настройки конкретно xdebug на сервере заканчиваются. Но
чтобы данный конфиг заработал нам необходимо в
/etc/hosts
указать что такое wsl.host
. На
самом деле мы ожидаем там увидеть IP адрес головной системы на
нашем ПК, а именно windows.
Изначально во всех инструкциях, которые я нашел, указывается что
нужно писать xdebug.remote_host=127.0.0.1
, но сеть в
WSL устроена таким образом, что 127.0.0.1 внутри linux будет
указывать именно на linux, а не windows. То есть дебаггер,
ожидающий подключения в PhpStorm не дождется этих подключений:)
В поисках решения этой проблемы я наткнулся на пост в интернете, откуда решил взять gif-ку что наглядности.
Небольшая гифка-пояснение
Автор поста предлагает свой github репозиторий с C# приложением, которое надо добавить в планировщик Windows чтобы команда выполнялась при каждом запуске ПК. У меня сходу этот скрипт не сработал, да и проводить какие-то кастомизации в Windows не хотелось.
Ценой нескольких часов я собрал "костыльный" bash скрипт,
который прописывает автоматически IP адрес хостовой системы в
/etc/hosts
внутри linux при каждом входе в WSL
инструкцию и скрипт выложил на github.
Но этот скрипт нужно запускать при первом запуске системы. Руками такое делать "не красиво", а стандартный systemd и rc.local через wsl не работают. Поэтому пришлось использовать костыльное и небезопасное, но рабочее решение.
- Создаем файл в корне системы
/startup.sh
с таким содержимым, даем ему права на запускchmod +x /startup.sh
- Даем права на запуск этого скрипта с sudo без пароля (иначе
доступа на запись в
/etc/hosts
нет) - Добавляем строчку
sudo /startup.sh
в/etc/profile
При каждом входе в wsl запускается скрипт, который прописывает
все что нужно в /etc/hosts
и по адресу
wsl.host
наш linux будет видеть windows. Если кто-то
знает как это можно достичь более правильным путем, буду благодарен
если отпишите способ в комментариях или можно лично.
После входа в wsl стоит проверить, что хост прописался пишем
команду cat /etc/hosts
и на последнем месте должно
быть что-то вроде этого:172.26.64.1 wsl.host
Настройка xdebug в PhpStorm на Windows
После завершения всех работ внутри WSL можно перейти к настройке дебаггера в PhpStorm
-
File->Settings->Languages & Framework->PHP
Открываем выбор интерпретаторов
Первый вариант "From Docker, Vagrant, VM, WSL, Remote"
Выбираем установленный WSL
Убеждаемся, что xdebug активирован
-
File->Settings->Languages & Framework->PHP->Debug
Активируем прослушивание дебаггера и указываем порт, который ранее указали в WSL (у меня это 9002, а изначально он 9000)
В итоге должно выглядеть примерно так
Убираем галочку в advanced напротив пункта "Pass required configuration options.."
Если ее не снять, то дебаггер будет передавать свои параметры по
умолчанию и они будут перезатираться в итоге наш
wsl.host
будет заменен на 127.0.0.1
и
ничего работать не будет.
Причем эта проблема проявляется только при отладке через консоль, т.к. при отладке HTTP сервера никакие конфиги не пробрасываются и забираются из ini файлов.
На этом все можно проверять работает ли дебаггер.
Проверка результата
- Ставим breakpoint в index.php на любой строчке в коде
- Переходим в браузере на этот файл и видимо, что дебаггер
заработал
- Для отладки консольного скрипта необходимо добавить
конфигурацию запуска скрипта
Добавляем конфигурацию Php Script
Указываем путь до скрипта и нужные аргументы
Сохраняем, закрываем и запускаем дебаггер
Вместо заключения
Таким образом, перелопатив несколько разных источников, статей, гистов я пришел к "почти идеальному" рабочему окружению при работе с PHP. Если есть где чего можно улучшить/доработать пишите в комментарии или в любой другой способ связи со мной.