Как подружить PHPstorm, xDebug и удаленные ветки, собранные через Docker? Слишком просто…

в 6:24, , рубрики: ci, devops, docker, php, php-fpm, xdebug, гайд, настройка, отладка, процесс разработки, Учебный процесс в IT

Доброго времени суток!

Еще год назад мой процесс отладки кода в PHP заключался в двух строчках:

var_dump($variable);
die();

Периодически, конечно, приходилось использовать более «сложные» конструкции:

console.log(data);

echo json_encode($variable, JSON_UNESCAPED_UNICODE);
exit();

Нет, что вы! Я знал — в наше время не подобает культурному программисту заниматься этим

древним ремеслом

шутка про другое древнейшее ремесло

Но, честно говоря, я всегда боялся того, что не понимаю. В том числе и принтеров xDebug, в особенности, как все это дело настроить. В один прекрасный день у меня получилось это сделать на своей машине и в локальном проекте — радости не было предела. Спустя много месяцев я столкнулся с новой проблемой, как заниматься отладкой в PHPstorm через xDebug, если проект собирается удаленно докером через CI.

Если Вы так же, как и я, испытываете трудности с настройкой разных штук, добро пожаловать под кат, я расскажу о своем опыте настройки окружения отладки с такими страшными словами, как Docker, xDebug, CI.

Для тех, кто не любит воду и хочет перейти непосредственно к сути настройки.

Почему стоит уйти от заплесневевших методов отладки и перейти на адекватные технологии?

Над катом я немного слукавил, я занимался кустарной отладкой не только потому, что боялся настроить что-либо, и не потому что слишком глупый, а просто потому, что у меня не было необходимости в чем-то более удобном. Чаще всего я работал над проектами, локально на своем довольно мощном компьютере, да и задачи были не настолько сложными, чтобы процесс отладки начал занимать достаточно весомую позицию.

В какой-то момент, я для себя осознал, что мне уже просто неудобно, и попытался подружить xDebug и PHPstorm при работе над локальным проектом. Беда в том, что большинство документаций и гайдов, которые я нашел, подразумевают, что читающий их человек довольно хорошо разбирается в предметной области и все понимает, в моем случае это было не так и на свою первую настройку xDebug я в сумме потратил 4-5 часов за 2 вечера. Это было довольно тяжело морально, я чувствовал себя бесконечно тупым. Тем не менее, настроить получилось, все работало!

Да, стало удобней, локально-дома, но на основной работе я занимался сайтами удаленно, и чаще всего у меня не было возможности либо выгрузить сайт локально (из-за слабой машины или неудобного процесса развертывания), либо влиять на настройки сервера из-за хостингов, поэтому вносил правки «на живую» и отладкой занимался через html-комментирование print_r (на той работе это было «нормально», хоть и не горжусь этим опытом).

image

Однако, 3 месяца назад я перешел в более крутую компанию и стал заниматься действительно серьезным проектом с высокой нагрузкой. И тут для меня многое изменилось. Инфраструктура и процесс разработки примерно такие: есть свой сервер GitLab, у каждого проекта есть свой репозиторий, в Jira приходят задачи, по номерам задачи создаешь ветку, при создании ветки с помощью CI автоматически создается своя песочница с сайтом, где ты спокойно работаешь, каждый push пересобирает ветку, по окончанию работ отдаешь на код-ревью, вливаешь ветку в мастер.

Все круто за исключением одного НО, каждый пересбор ветки в моем случае занимает примерно 10 секунд. В процессе самой разработки это несущественное время, так как я уже перешел ту стадию, когда приходилось проверять работоспособность кода чуть ли не каждую строчку из-за неуверенности и малого опыта. Однако, когда я переходил к отладке, эти 10 секунд начали играть ощутимую роль. Процесс подобной отладки выглядел в итоге так:

  • Добавляю 2 строчки
  • Пушу коммит
  • Жду 10 секунд
  • Проверяю, смотрю, что не так
  • Repeat

По приблизительным подсчетам, готовая к мержу ветка имела примерно 20% полезных коммитов и 80% коммитов отладки. Допустим, я закончил работу над веткой с 300 коммитами, из них 240 коммитов по сути просто отжирали 40 минут моего рабочего времени (и это только время ожидания сборки ветки, не учитывая те секунды, которые складываются в минуты, на то, чтобы добавить 2 строчки и потом их удалить).

image

В какой-то момент мне это надоело и я решил-таки настроить xDebug, чтобы процесс отладки стал менее затратным. К несчастью, мои нынешние коллеги либо не пользовались этой технологией (жду шутки про «Устроился в крутую компанию, где никто не пользуется xDebug'ом»), либо не зналине помнили, как подружить IDE с xDebug'ом, в случае когда ветка собирается удаленно через CI, а так как я ни разу не devOps и как я упомянул выше, процесс настройки чего-либо является для меня достаточно мучительным процессом, это вылилось примерно в 6 часов чистого времени, чтобы наконец все заработало, и я понимал процесс, и это было бы достаточно удобно.

Процесс настройки

Я не буду вдаваться в подробности, как прикручивать CI, Docker, в общем, как собрать инфраструктуру, предполагается, что это уже все готово и осталось только настроить свое личное окружение.

Допустим, наш репозиторий имеет примерно такую структуру:

image

Для начала нам нужно проверить, есть ли в текущем образе сам xDebug, для этого можете воспользоваться phpinfo();

Если xDebug уже включен в сборку — отлично, если нет, то ознакомьтесь с этим источником, который помог мне непосредственно в самой настройке, однако я пошел немного по другому пути.

Настраиваем php.ini

Для того, чтобы в итоге все заработало, нам важны 2 настройки xDebug:

  • xdebug.remote_enable
  • xdebug.remote_host

В итоговой сборке удаленной ветки remote_enable должен быть включен, а в remote_host должен быть присвоен IP вашего компьютера в сети. Давайте включим эти настройки в наш билд.

Для начала нужно узнать где хранятся настройки php, они могут располагаться либо в /usr/local/etc/php/conf.d/php.ini, либо сам файл .ini может быть назван иначе, в моем случае это /usr/local/etc/php/conf.d/php-settings.ini. Узнать это можно из настроек собираемого образа.

Создаем в нашей ветке свои дополнительные настройки через тот же файл php-settings.ini, а расположим его в ./build_env/php/php-settings.ini
Прописываем в нем 2 вышеупомянутые настройки:
xdebug.remote_enable = on
xdebug.remote_host = IP.ВАШЕГО.КОМПЬЮТЕРА.ВСЕТИ

Далее нам нужно добавить этот файл к «родительским» настройкам образа. Я делаю это через volumes путем добавления в ./build_env/docker-compose/docker-compose.tmpl строчки:
- ${PROJECT_DIR}/build_env/php/php-settings.ini:/usr/local/etc/php/conf.d/php-settings.ini

Примерно так в итоге выглядит docker-compose.tmpl в моем проекте:

image

При следующей сборке ветки, можно проверить привязались ли новые настройки через тот же phpinfo();, если да — отлично, если нет — Вам не повезло и придется пройти тот же путь, что проделал я в первый раз :(

Настраиваем маппинги в PHPstorm

Далее нужно настроить сам PHPstorm. Я решил не использовать DBgp Proxy, чтобы не настраивать маппинги во всплывающем окне каждый раз. В моем случае я использую шаблон сервера, который будет содержать в себе необходимые маппинги.

Переходим в Settings / Preferences | Languages & Frameworks | PHP | Servers

  1. Создаем шаблон сервера
  2. Name: BRANCH
  3. host: любой, он не влияет
  4. port: любой, он не влияет
  5. Debugger: xDebug
  6. Ставим галку на Use path mappings
  7. Проставляем соответствующие маппинги, рабочие локальные папки должны соответствовать папкам на сервере, где располагаются собранные ветки, в моем случае собранные билды находятся в папке /var/www/builds/your_namespace/your_project/your_branch

image

Сохраняем эти настройки, менять мы их будем каждый раз, когда работаем с новой веткой. Например, если сегодня работаю с веткой web-2233 то поменяю маппинг на /var/www/builds/путь_до_билда/web-2233

Добавляем новую переменную окружения, чтобы IDE автоматически подтягивала маппинги

Теперь довольно важный и не самый очевидный момент. Когда мы начинаем дебаг, PHPstorm должен понимать, какие локальные файлы соответствуют файлам на удаленном сервере. Если сервер не передал ему конкретную установку, то появится всплывающее окно, в котором нужно проставить соответствия путей вручную. Для того, чтобы PHPstorm сразу брал маппинги от сервера с названием BRANCH нужно добавить в нашу сборку переменную окружения PHP_IDE_CONFIG

В ./build_env/docker-compose/docker-compose.tmpl создаем новую переменную окружения в environment:
PHP_IDE_CONFIG: ${PHP_IDE_CONFIG}

image

В .gitlab-ci.yml задаем эту переменную:
- export PHP_IDE_CONFIG="serverName=BRANCH"

image

Готово!

Нам не нужны расширения для браузера, не нужно передавать в get-параметры URL XDEBUG_SESSION_START=IDE_KEY, не нужно добавлять дополнительные конфигурации.

Достаточно просто включить прослушку image и обновить страницу сайта, как только мы наткнемся на первый брекпоинт, выполнение приложение остановится на нем

image

Спасибо за внимание, надеюсь эта статья будет полезна и кто-нибудь сэкономит время, не наступая на те же грабли, что и я :)

Источники, которые я использовал при первичной настройке:
https://gist.github.com/chadrien/c90927ec2d160ffea9c4
https://confluence.jetbrains.com/display/PhpStorm/Docker+Support+in+PhpStorm#DockerSupportinPhpStorm-DebuggingthePHPwebapplicationrunningintheDockercontainer

Автор: Пересада Егор

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js