PhpStorm + Docker + Xdebug

В этой небольшой статье я опишу рабочее решение настройки Xdebug для использования его при отладке в PhpStorm с использованием удаленного интерпретатора PHP, работающего внутри Docker-контейнера.

В итоге получится конфигурация на базе окружения в Docker-контейнерах, которая позволит производить отладку Web-приложения, консольного приложения, тестов, запускаемых из консоли и запускаемых из PhpStorm.

Исходные данные

У вас должны быть установлены Linux, PhpStorm, Docker, Docker-compose. Если Вы ведете разработку не на Linux, то Вам, наверное, придется чуть сложнее, но раз Вы читаете эту статью, значит Вы уже озадачились вопросом отладки с использованием php в контенере Docker и у Вас уже всё давно установлено. Если настройки для MacOS или Windows будут отличаться от приведенных в статье, я обязательно укажу на это.

Статья будет рассмотрена на следующем примере. Каталог на локальной машине (хосте), в котором планируется разработать некоторое приложение: /home/denis/code/docker-xdebug. При этом корень Web-сервера находится в подкаталоге public. Основной каталог проекта отображается внутрь Docker-контейнеров на каталог /var/www. Внутри Docker-контейнера, при этом, получаем путь к корневому каталогу Web-сервера /var/www/public — именно на него настроен Web-сервер nginx.

Пример конфигурации

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

Решение проблемы оказалось достаточно простым. Я просто создал общую сеть для бандла в docker-compose (192.168.220.0/28) и таким образом добился одинакового IP-адреса хоста (192.168.220.1) на всех машинах членов команды разработки.

Если Вы используете MacOS или Windows, то вместо адреса 192.168.220.1 Вам нужно будет указать host.docker.internal в приведенном ниже docker-compose.yml.

Ниже приведу подробную инструкцию и все файлы, необходимые для сборки бандла с рабочей отладкой Xdebug.

В файлах отсутствует установка каких либо дополнительных зависимостей и расширений, так как в каждом проекте они свои. Это выходит за рамки данной статьи. Вы должны сами добавить их при необходимости.

docker-compose.yml

version: '3'
services:
  php-fpm:
    build:
      context: docker/php-fpm
    volumes:
      - ./:/var/www
    environment:
      XDEBUG_CONFIG: "remote_host=192.168.220.1 remote_enable=1"
      PHP_IDE_CONFIG: "serverName=Docker"
    networks:
      - internal
  nginx:
    build:
      context: docker/nginx
    volumes:
      - ./:/var/www
    ports:
      - "80:80"
    depends_on:
      - php-fpm
    networks:
      - internal
networks:
  internal:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 192.168.220.0/28

Если у вас MacOS или Windows, то вместо remote_host=192.168.220.1 используйте remote_host=host.docker.internal.

docker/php-fpm/Dockerfile

FROM php:7.1-fpm

RUN apt-get update && apt-get install -y wget git unzip \
    && pecl install xdebug-2.6.1 \
    && docker-php-ext-enable xdebug

ADD ./php.ini /usr/local/etc/php/php.ini

RUN wget https://getcomposer.org/installer -O - -q \
    | php -- --install-dir=/bin --filename=composer --quiet

WORKDIR /var/www

docker/php-fpm/php.ini

max_execution_time = 1000
max_input_time = 1000

Это необходимо для того, чтобы Вы успели изучить результаты отладки до истечения таймаута запроса.

docker/nginx/Dockerfile

FROM nginx

ADD ./default.conf /etc/nginx/conf.d/default.conf

WORKDIR /var/www

docker/nginx/default.conf

server {
    listen 80;
    index index.php;
    server_name 127.0.0.1 localhost;
    root /var/www/public;

    location / {
        try_files $uri /index.php?$args;
    }

    location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php-fpm:9000;
        fastcgi_index index.php;
        fastcgi_read_timeout 1000;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
}

Теперь просто запускаем бандл docker-контейнеров:

$ docker-compose up -d --build

Настройка PhpStorm

Настройка отладки в PhpStorm типичная для подобных ситуаций. Необходимо в настройках (File — Settings) проделать следующее:

Добавить Docker сервер

Если он у Вас еще не добавлен, конечно. Для этого откройте настройки: «Build, Execution, Deployment» — Docker. Затем нажмите плюсик, чтобы добавить новое подключение к докеру. У меня все подключилось сразу же в режиме Unix socket. Нажмите Apply.

Добавление нового Docker сервера

Добавить внешний интерпретатор

Откройте настройки: «Languages & Frameworks» — PHP

Справа от CLI Interpreter нажмите кнопку с тремя точками.

Переход к настройке интерпретаторов

В открывшемся окне CLI Interpreters нажмите плюс слева вверху и выберите там From Docker….

Далее нужно выбрать Docker (либо в новых версиях PhpStorm можно также выбрать Docker Compose). Второй вариант мне показался удобней, так как в этом случае я вижу контейнеры только данного проекта, а не все существующие на хосте (у меня их довольно много).

Два варианта на выбор:

Docker
Docker Compose

Не забывайте правильно указывать наименование образа или сервиса. Нажмите ОК, после чего будет произведена попытка добавления выбранного интерпретатора из Docker.

В случае удачи, вы увидите следующее окно (здесь видно, что была определена версия PHP, конфигурационный файл PHP, а также, что очень важно, версия Xdebug. Переименуйте интерпретатор в нечто более понятное, например, как на скриншоте ниже. Нажмите OK.

Корректно добавленный интерпретатор из Docker

Теперь Вы должны увидеть следующее:

Выбран внешний интерпретатор Docker

Нажмите Apply.

Проверить конфигурацию Xdebug

Откройте настройки: «Languages & Frameworks» — PHP — Debug. И нажмите на ссылку Validate.

Нажмите Validate для проверки настройки

Откроется окно, в котором Вы должны указать полный путь к web-корню (в нашем примере это подкаталог public) и адрес сервера (в нашем примере порт 80 контейнера nginx транслируется в порт 80 хоста, поэтому в адресе порт не указывается. Если Вы транслировали в другой порт хоста — укажите обязательно его). Нажмите Validate.

Результаты проверки настроек Xdebug

Если у Вас результат проверки выглядит так же, то Вы все настроили правильно. Закройте окно Validate Debugger Configuration.

Добавить PHP сервер

Откройте настройки: «Languages & Frameworks» — PHP — Servers и нажмите плюсик, чтобы добавить новый.

Укажите имя сервера Docker (должно совпадать с переменной окружения PHP_IDE_CONFIG в docker-compose.yml) и хост 127.0.0.1. Затем ниже включите опцию Use path mappings и укажите соответствие между локальным каталогом проекта и этим же каталогом проекта внутри Docker-контейнера. Это соответствие изначально настраивается в docker-composer.yml для службы php-fpm в разделе volumes. Затем нажмите OK.

Новый PHP сервер с отображением локального каталога на каталог контейнера

Добавить конфигурацию для запуска

Остался последний штрих — добавление конфигурации запуска. Мы добавим простую Web-страницу.

В главном меню Run перейдите в Edit configurations…

В открывшемся окне нажимайте плюсик вверху слева и выбирайте PHP Web page. Укажите имя для данной страницы, например, WWW, затем укажите сервер, с которым связана эта страница (мы создали его на предыдущем шаге) и нажмите OK.

Конфигурация Web сервера для отладки

Запуск отладки

Теперь пришло время приступить к самой отладке.

В подкаталоге проекта public создайте файл index.php с следующим содержимым:

<?php
$s = $_SERVER;
phpinfo();

Вверху справа на панели запуска выберите созданную конфигурацию и нажмите зеленый треугольник.

Это действие должно запустить сервер, который откроет в браузере файл index.php, в результате чего в браузере должен быть отображен результат работы phpinfo().

Результат работы phpinfo()

Отладка WEB-приложения

Устанавливаем точку останова на строку phpinfo();

И вместо зеленого треугольника нажмем кнопку с зеленым жуком — это запустит сервер в режиме отладки.

При первом запуске отладки в браузере вам возможно понадобится специальное расширение JetBrains IDE Support, которое обычно предлагается к установке автоматически. Установите его.

При запуске отладки, откроется браузер с URL, к которому будет добавлен параметр с идентификатором сессии отладки, что-то вроде: http://127.0.0.1/?XDEBUG_SESSION_START=11223

При этом вывод в браузер не будет выполнен, так как сработает точка останова. Вернитесь в окно PhpStorm. Активная точка останова выглядит вот так:

Активная точка останова

В данном случае птичкой обозначается та точка (а их может быть несколько), на которой произошел останов. Все переменные выше будут подсвечены их значениями для удобства.

Теперь переместимся ниже — на панель отладки.

Панель отладки PhpStorm

На ней видна вся отладочная информация. Справа — значения всех переменных в текущей области видимости (здесь также видна наша переменная $s), слева виден стек вызовов (сейчас он пуст, так как у нас примитивный пример). Имеются кнопки на левой панели, при помощи которых можно перезапустить отладку, прервать отладки продолжить выполнение с этого места, остановить отладку и другие. На верхней панели имеются кнопки, при помощи которых можно управлять отладкой: проходить пошагово каждое действие, начиная с точки останова, перепрыгивать функции, не заходя во внутрь и т.д.

Также существует другой способ отладки — при помощи «прослушивания». Нажмите кнопку с телефонной трубкой, чтобы активировать режим прослушивания.

После того, как кнопка изменит вид (с красного запрещающего знака на зеленые полоски), Вы можете просто открыть веб-приложение в браузере и, если в коде проставлены точки останова, режим отладки запустится автоматически.

Отладка консольного приложения (CLI)

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

Теперь можно запустить консольный скрипт следующей командой:

$ docker-compose exec php-fpm php ./public/index.php

Если при этом отладка не сработала, убедитесь, чтобы имя сервера, которое создавали выше, совпадало с именем сервера в файле docker-compose.yml в переменной окружения PHP_IDE_CONFIG.

После окончания отладки не забудьте отключить режим прослушивания.

Отладка тестов (PhpUnit)

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

$ docker-compose exec php-fpm ./vendor/bin/phpunit

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

Откройте настройки: «Languages & Frameworks | PHP | Test Frameworks». И добавьте новый фреймворк (нажмите кнопку с плюсиком) — PHPUnit by Remote Interpreter. В открывшимся окне выберите наш интерпретатор и нажмите ОК.

Настройка интерпретатора для PHPUnit

Затем необходимо указать путь к autoload.php и путь к phpunit.xml и нажать ОК.

Настройка PHPUnit

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

Для этого в главном меню Run перейдите в Edit configurations…

Нажмите плюсик и добавьте PhpUnit. Укажите удобное Вам имя, например Tests и установите переключатель запуска в Defined in the configuration file. Теперь Вы можете настраивать тесты через конфигурационный файл phpunit.xml.

Конфигурация запуска тестов PHPUnit

Теперь точно так же кнопкой с зеленым треугольником на панели запуска Вы можете запускать тесты в обычном режиме, кнопкой с жуком — запускать тесты в режиме отладки и кнопки с щитом запускать тесты в режиме расчета покрытия тестами (для расчета покрытия Вы должны настроить блок whitelist в конфигурационном файле phpunit.xml).

При этом активировать режим прослушивания (кнопка с трубкой) уже не нужно.

Резюме

В данной статье был описан простой способ настройки и использования отладчика Xdebug в PhpStorm, если используется удаленный интерпретатор в виде Docker-контейнера.

Все файлы можно скачать на GitHub:
https://github.com/denisbondar/docker_php-fpm_xdebug

После того, как Вы склонируете себе репозиторий, не забудьте выполнить composer install для установки зависимостей и создания автозагрузчика.

$ docker-compose exec php-fpm composer install

PhpStorm + Docker + Xdebug: 2 комментария

Прокомментировать