Под катом небольшая заметка про то как можно настроить удобное окружение для работы с 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://habr.com/ru/news/t/516054) и я решил все же сделать удобное окружение для своей работы.
Теперь к делу
Базовая установка системы
Как установить WSL на Windows есть множество инструкций. Я все сделал по официальному мануалу с сайта Microsoft
После успешной установки в PowerShell нужно написать команду wsl и мы погружаемся внутрь Linux, который внутри Windows
Далее идет череда стандартных команд для настройки веб сервера на Ubuntu:
sudo apt update
sudo apt upgrade
sudo apt install apache2
sudo apt install php libapache2-mod-php php-mysql php-xml php-curl
sudo 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 install php-xdebug
Открываем
sudo nano /etc/php/7.2/mods-available/xdebug.ini
и приводим к такому содержимому
zend_extension=xdebug.so xdebug.remote_enable=true xdebug.remote_host=wsl.host xdebug.remote_port=9002 xdebug.profiler_enable=1 xdebug.profiler_output_dir=/tmp xdebug.remote_autostart=on xdebug.idekey=PHPSTORM xdebug.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. Если есть где чего можно улучшить/доработать пишите в комментарии или в любой другой способ связи со мной.