Настройка Xdebug3 для Laravel-приложения в Docker

от автора

Начнём пожалуй, со структуры, в которой всё будет:

docker/ ├── docker-compose.yml ├── .env ├── .env.example ├── .gitignore └── services     ├── database     │   ├── dump     │   └── .gitignore     ├── nginx     │   └── site.conf     └── php         ├── Dockerfile         └── php.ini

А теперь обо всём по порядку:

Файл .gitingore содержит только одну строчку /.env

Файл .env.example в начале проекта такой же, как и .env

В файле docker-compose.yml содержится информация про все наши сервисы:

version: "3.7" services:   php:     build:       args:         uname: ${PHP_UNAME}         uid: ${PHP_UID}         gid: ${PHP_GID}       context: ./services/php     container_name: ${PROJECT_NAME}_php     image: ${PROJECT_NAME}_php     restart: unless-stopped     working_dir: /var/www/     volumes:       - ./services/php/php.ini:/usr/local/etc/php/php.ini       - ../:/var/www     environment:       COMPOSER_MEMORY_LIMIT: 2G       XDEBUG_CONFIG: client_host=${XDEBUG_REMOTE_HOST} client_port=${XDEBUG_STORM_PORT} remote_enable=1       PHP_IDE_CONFIG: serverName=${XDEBUG_STORM_SERVER_NAME}     networks:       - main_network     depends_on:       - db   db:     image: mysql:5.6     restart: unless-stopped     container_name: ${PROJECT_NAME}_db     command: --default-authentication-plugin=mysql_native_password     environment:       MYSQL_DATABASE: ${DB_DATABASE}       MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}       MYSQL_PASSWORD: ${DB_PASSWORD}       MYSQL_USER: ${DB_USERNAME}     ports:       - ${DB_LOCAL_PORT}:3306     volumes:       - ./services/database/dump:/var/lib/mysql     networks:       - main_network    nginx:     image: nginx:1.17-alpine     restart: unless-stopped     container_name: ${PROJECT_NAME}_nginx     ports:       - ${NGINX_LOCAL_PORT}:80     volumes:       - ../:/var/www       - ./services/nginx:/etc/nginx/conf.d     networks:       - main_network     depends_on:       - php networks:   main_network:     driver: bridge     name: ${PROJECT_NAME}_main_network     ipam:       driver: default       config:         - subnet: ${SUBNET_IP}/${SUBNET_MASK} 

Из важного здесь стоит отметить ./services/php/php.ini:/usr/local/etc/php/php.ini — наш локальный файл php.ini (там некоторые конфиги дебаггера) будет намаплен на тот что внутри контейнера. XDEBUG_CONFIG — будет задана переменная окружения внутри контейнера php, которую потом будет испльзовать xdebug вместо значений по-умолчанию. Здесь мы задаем client_host — хост, к которому xdebug будет пытаться подключиться при инициации отладочного соединения. Этот адрес должен быть адресом машины, на которой ваш PhpStorm прослушивает входящие отладочные соединения. Получается так, что наша локальная машина находится в одной подсети с запущеными контейнерами, а её адресс будет первым в этой подсети. Таким образом, мы всегда можем знать каким будет адресс нашей машины, и позже зададим это значение в переменную XDEBUG_REMOTE_HOST . В CLIENT_PORT нужно будет задать порт, установленный на прослушивание в IDE (9003). XDEBUG_STORM_SERVER_NAME — имя сервера, который мы создадим в IDE позже. Этот параметр нужен, чтобы сообщить PhpStorm, как сопоставлять пути при подключении с докера (ведь у вас же открыты локальные файлы в редакторе, а код работает на удалённых; хотя при испльзовании volumes это не совсем так).

Вот, как выглядит файл окружения .env :

PROJECT_NAME=my_project  DB_DATABASE=my_project_db DB_USERNAME=my_project DB_PASSWORD=p@$$w0rd DB_ROOT_PASSWORD=toor  PHP_UNAME=dev PHP_UID=1000 PHP_GID=1000  DB_LOCAL_PORT=3377 NGINX_LOCAL_PORT=8077  XDEBUG_STORM_SERVER_NAME=Docker XDEBUG_REMOTE_HOST=192.168.227.1 XDEBUG_STORM_PORT=9003  SUBNET_IP=192.168.227.0 SUBNET_MASK=28 

На счёт подсети для проекта, то здесь мы задали 192.168.227.0 с маской 28, то-есть для всех устройств остаётся 32 - 28 = 4 бита, что равносильно 2 ** 4 - 1 = 15 контейнеров. Не 16 потому что в подсеть входит также наша локальная машина, которая, кстати, будет иметь адресс 192.168.227.1. Именно это значение мы задали в переменную XDEBUG_REMOTE_HOST.

Настройки веб-сервера site.conf:

server {     listen 80;     server_name 127.0.0.1 localhost;     client_max_body_size 5m;      error_log  /var/log/nginx/error.log;     access_log /var/log/nginx/access.log;      root /var/www/public;     index index.php;      location / {         try_files $uri $uri/ /index.php?$query_string;         gzip_static on;     }      location ~ \.php$ {         try_files $uri =404;         fastcgi_split_path_info ^(.+\.php)(/.+)$;         fastcgi_pass php:9000;         fastcgi_index index.php;         include fastcgi_params;         fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;         fastcgi_param PATH_INFO $fastcgi_path_info;     } }  

В нашем Dockerfile (тот что для php) нужно не забыть установить и включить xdebug. Для этого добавляем 2 строчки:

RUN pecl install xdebug RUN docker-php-ext-enable xdebug

Стоит отметить, что будет испльзована последняя (то-есть 3) версия (есть различия в конфигурации по сравнению с 2).

Полный Dockerfile:

FROM php:7.4-fpm  # Arguments defined in docker-compose.yml ARG uname ARG gid ARG uid  # Install system dependencies RUN apt-get update \     && apt-get install -y \         git \         curl \         dpkg-dev \         libpng-dev \         libjpeg-dev \         libonig-dev \         libxml2-dev \         libpq-dev \         libzip-dev \         zip \         unzip \         cron  RUN pecl install xdebug RUN docker-php-ext-enable xdebug  RUN docker-php-ext-configure gd \   --enable-gd \   --with-jpeg  ADD ./php.ini /usr/local/etc/php/php.ini  # Clear cache RUN apt-get clean && rm -rf /var/lib/apt/lists/*  # Install PHP extensions RUN docker-php-ext-install pdo pdo_mysql pdo_pgsql pgsql mbstring exif pcntl bcmath gd sockets zip  # Get latest Composer COPY --from=composer:latest /usr/bin/composer /usr/bin/composer  # Create system user to run Composer and Artisan Commands RUN groupadd --gid $gid $uname RUN useradd -G www-data,root -s /bin/bash --uid $uid --gid $gid $uname  RUN mkdir -p /home/$uname/.composer && \     chown -R $uname:$uname /home/$uname  # Set working directory WORKDIR /var/www  USER $uname  # Expose port 9000 and start php-fpm server EXPOSE 9000 CMD ["php-fpm"] 

Также, зададим некоторые параметры исплнения в php.ini :

max_execution_time=1000 max_input_time=1000 xdebug.mode=debug xdebug.log="/var/www/xdebug.log" xdebug.remote_enable=1

Запустим наше приложение:

docker-compose up -d

И дальше пойдём в PhpStorm для настройки:

Создадим сервер с названием Docker и cделаем маппинг локального корня проекта (/var/www/quizzy.loc) на путь, по которому он лежит в докере (/var/www):

Дальше, нам нужно будет настроить использование интерпретатора php из докера:

Настраиваем php interpreter
Настраиваем php interpreter
Выбираем сервис, в котором находится php и указываем путь к интерпретатору
Выбираем сервис, в котором находится php и указываем путь к интерпретатору
Задаём параметры запуска (через exec)
Задаём параметры запуска (через exec)

Теперь можем перейти в подпункт «Debug» и настроить порт на котором запускать:

Настраиваем дебаггер
Настраиваем дебаггер

Проверим, работает ли Xdebug:

Теперь можем поставить брейкпоинт в нашем коде и начать прослушивание входящих подключений:

Переходим в наш любимый браузер Firefox, устанавливаем и включаем плагин на нужной странице:

Перезагружаем страницу, и в PhpStrom должен поймать подключение:

ссылка на оригинал статьи https://habr.com/ru/post/540072/