Гайд для remote подключения. Постарался обьяснить максимально подробно для новичков, так как понимаю как больно прыгать по статьям и теряться в последовательности. Тема актуальная, в силу того, что локалки не у всех мощные - иногда проще работать через виртуалку. Надеюсь моя бессонная ночь с загадкой о проблеме поможет кому нибудь справиться с этим за полчаса.
Предварительно необходимо убедиться, чтобы в контейнере под php-fpm у вас был пакет Xdebug. Нужно либо установить в ручную, либо зашить в Dockerfile - конечно же второе будет лучше, т.к не придется при перезапуске делать одно и то же действие с установкой.
Мой DockerFile пример с командами установщика ( для удобства прикрепляю целиком, чтобы вы не гадали какой порядок тех или иных команд )
Dockerfile
FROM php:8.1-fpm
USER root
RUN apt-get update && apt-get install -y \
apt-utils \
libpq-dev \
curl \
libpng-dev \
iptables-persistent \
libzip-dev \
libfreetype6-dev \
libjpeg62-turbo-dev \
zip unzip \
iputils-ping \
git && \
docker-php-ext-install pdo_mysql && \
docker-php-ext-install bcmath && \
docker-php-ext-configure gd --with-freetype --with-jpeg && \
docker-php-ext-install gd && \
docker-php-ext-install zip && \
docker-php-ext-install exif && \
pecl install xdebug && \
docker-php-ext-enable xdebug && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
COPY ./.docker/php/conf.d/php.ini /usr/local/etc/php/conf.d/php.ini
COPY ./.docker/php/conf.d/xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini
RUN rm /usr/local/etc/php-fpm.d/www.conf
COPY ./.docker/php/conf.d/www.conf /usr/local/etc/php-fpm.d/www.conf
# Install composer
ENV COMPOSER_ALLOW_SUPERUSER=1
RUN curl -sS https://getcomposer.org/installer | php -- \
--filename=composer \
--install-dir=/usr/local/bin
WORKDIR /var/www/myproject
Также в конфигурации xdebug.ini, которая должна лежать по пути /php/conf.d/xdebug.ini
Должны быть следующие настройки
xdebug.start_with_request=yes
xdebug.mode=debug
xdebug.client_host=<ваш белый айпи>
xdebug.log="/tmp/xdebug.log"
xdebug.client_port=9003
xdebug.idekey=PHPSTORM
Если все ок перезапускаем контейнера на всякий случай с флагом билд
sudo docker-compose up -d —build
Если не ок, то разбираемся с докером.
1.1 Настройки роутера
-
Убедитесь, что у вас белый айпи на роутере
Для этого можно попробовать перезагрузить роутер и посмотреть меняется ли ip например на сайте 2ip
По умолчанию услуга статического айпи не включена в стоимость, поэтому ее необходимо докупить у провайдера, провалившись в личный кабинет вашего провайдера и после этого перезагрузить роутер - у вас появится новый айпи, который не должен меняться при повторной перезагрузке.
-
После того как вы убедились, что ip статический (белый) - необходимо пробросить порты на роутере. Для этого провалитесь по адресу http://192.168.0.1 для некоторых роутеров, или http://192.168.1.1 - в форме логина, если никто не менял пароли можно посмотреть креды на обратной стороне роутера. По умолчанию это что то типа admin:admin.
В панели настроек найдите раздел с port forwarding. ( он может находиться в network или в разделе сетевой экран )
Необходимо открыть 9003 порты для wan сети, добавив строку в таблице для протоколов TCP&UDP. В некоторых ситуациях нужно также указать ip назначения - это может быть в контексте вашего локального устройства, или устройства, которое отправляет запросы (ip виртуалки). В моем случае это было локальное устройство. Посмотреть айпи устройства в локальной сети можно с помощью команды
ipconfig getifaddr en0
в случае если у вас macos и нету кабеля ethernet напрямую в устройство. Если кабель есть то вместо 0 на конце команды поменяйте на единицу.После открытия портов на всякий случай можно перезагрузить роутер
-
Чтобы убедиться, что у нас нет ошибок на уровне портов и коннекта необходимо проверить это дело следующим образом:
-
Для проверки запросов можно использовать простую утилиту dbgpClient от xdebugger. Ее можно установить по ссылке и запустить из терминала локальной машины с помощью ./dbgpClient-macos
Он начнет прослушивать порт 9003 и напишет
Waiting for debug server to connect on port 9003.
В случае , если 9003 порт уже занят - мы можем его убить с помощью
sudo kill -9 <PID>
а сам PID посмотреть с помощью командыsudo lsof -i :9003
После запуска кидаем запрос с самой локальной машины на себя же с помощью команды
telnet 127.0.0.1 9003
(если нет telnet , то установите эту утилиту командойbrew install telnet
. Если нет homebrew - то устанавливайте его )Если запрос прошел успешно в окне терминала с запущенной утилитой xdebug появится строка коннекта. Если же нет, то скорее всего у вас включен брэндмауэр с блокировкой доступов ( другими словами firewal ) - который можно выключить в системных настройках -> конфиденциальность и безопасность (в разделе брэндмауэра).
-
-
Для проверки с виртуалки (заходим на виртуалку) и делаем так:
curl -Iv <белый ip>:9003
-
Возможно придется установить curl , если он выдаст ошибку curl not found. Установить вы его можете следующими командами для ubuntu
sudo apt update
sudo apt install curl
И проверьте что он установлен корректно
curl –version
Если курл прошел успешно в окне терминала с запущенной утилитой xdebug появится строка:
Connect from <ip виртуалки>:<port>
Если курл не прошел, то возможно на виртуальной машине также есть настройки файрвола , которые запрещают 9003 порт. Ну и для теста можно попытаться и установить правила разрешения в ручную через утилиту ufw -
sudo ufw status
(проверка портов) -
В xdebug.ini ставим белый айпишник, перебилдим контейнера на всякий случай и можно переходить к настройкам IDE.
1.2 Настройки PhpStorm
Предварительно добавьте ssh конфигурацию со своим удаленным сервером в IDE, чтобы не подключаться по ssh каждый раз руками.
-
Сначала в настройках IDE вам необходимо создать сервер для php интерпретатора.
Зайдите в Preferences IDE -> PHP -> Servers и создайте сервер, если ваш сайт работает на домене, в разделе host надо указать домен без протокола (example.com) , если на домене не установлен https - указываем порт 80, если установлен , то указываем 443 порт
Ставим галку на Use path mappings.
Далее переходим в раздел PHP->Debug и в Xdebug подразделе указываем 9003 порт , ставим галку на can accept external connections и на остальных 3х пунктах ниже
-
Следующим пунктом нужно настроить удаленный php интерпретер - для этого переходим в сам раздел php, где строка CLI интерпретера в правом углу нажимаем троеточие, в левом сайдбаре нажмем плюсик и создадим новую конфигурацию для интерпретера
В Name вводим что угодно , выбираем ssh конфигурацию с нашей виртуалкой и в php executable указываем путь до php (стандартно он будет /usr/bin/php)
Остальное по вашему желанию, для меня это было не обязательно, не забудьте сохранить все и убедиться что в настройках PHP подтянулась новая конфигурация в строке CLI интерпретера, а также появилась строка path mappings
-
Теперь в правом верхнем углу IDE находим дропдаун слева от зеленого жучка , нажимаем ПКМ и переходим в edit configuration. Здесь необходимо создать конфигурацию для процесса дебага
Создаем на плюсик в левом сайдбаре PHP Remote Debug, имя любое
Сервер выбираем , который мы создавали
Ставим галку на filter debug by ide key и вводим в поле ide key строку
“PHPSTORM” - без кавычек.
После этого переходим к следующему этапу:
1.3 Расширение xdebug helper и отладка
В зависимости от браузера вам нужно установить расширение которое должно называться Xdebug Helper
Далее зайти в его параметры через ПКМ по иконке расширения и в контекстном меню пункт Параметры , где указать IDE KEY “PHPSTORM” - без кавычек
Переходим на домен или ip сервера, который вы указывали в конфигах IDE - PHP -> Servers. Нажимаем на расширение и выбираем режим debug в выпадающем списке.
Кидаем запрос еще раз и открываем IDE , в разделе debugger должен пойти процесс отлова брейкпоинтов
Приятной всем отладки!
ivankudryavtsev
Все программисты делятся на две группы: те, кто пользуются дебаггерами и те, кто считает дебаггеры уделом пораженческого подхода к разработке…
Если мне хочется воспользоваться дебаггером для своего кода, значит он отстойный и я проиграл в этом раунде, надо переделывать. Это еще можно понять, если речь про системные языки программирования с утечками памяти, типа C/asm или отладкой сторонних либ, но PHP… Вам в помощь сила декомпозиции и юнит-тесты, если не помогло, добавьте логов и трейсинг типа OTLP.
Конструктивно: формат шпаргалки неудобен для читателя. Если для себя писали, могли бы и на гитхабе документик в маркдауне создать. Здесь - для людей.
warhamster
Дебаггер - очень удобный инструмент для работы в первую очередь с чужим кодом. В режиме "чукча не читатель" он, конечно, особо ни к чему...
adss332 Автор
Спасибо за отзыв , поправлю формат) не ожидал, что выложат с первого раза
Vitaly48
Как то очень категорично. А чем дебаг в условном go или java отличается от дебага в php?
ivankudryavtsev
Ничем, по сути, ни там ни сям нет фокусов с указателями и есть понятные стектрейсы.
Vitaly48
Тогда я не понимаю почему плохо пользоваться дебаггером в php
ivankudryavtsev
А я не про php, а про дебаггер, в целом. Это мое мнение, но если Вам нужен дебаггер для кода, для которого есть исходный код и тем более написан Вами, то Вы просто написали плохой код, в котором не смогли контролировать сложность, нет тестов и т.п.
Дебаггеры в низкоуровневых языках типа C/C++ могут помочь, если случайно происходит неверная работа с памятью, хотя тоже сомнительно. Пишите функции с разумной сложностью и тесты на них и никакие дебаггеры Вам не понадобятся.
Vitaly48
Я правильно понимаю что код который вы пишите работает сразу же и без каких либо ошибок?
ivankudryavtsev
Я пишу много тестов :) как только они все работают - код рабочий.
А причины в том, что (а) я не настоящий программист, поэтому чувство уверенности у меня не очень высокое; (б) я настолько ленивый, что при изменении кода я хочу сразу понимать что сломалось и где, а не разгадывать детективные истории.
Ну и по этой же причине, я не очень люблю языки с динамической типизацией, хотя раньше много писал на Perl и Python. Сейчас, преимущественно на Rust и Python. На первом вся функциональность, на втором весь бокс-мувинг.
Вообще, у людей, которые TDD или нечто подобное практикуют, "рабочесть" кода определяется "рабочестью" юнит-тестов и интеграционных тестов. Если находится баг, я пишу на него тесты. Более того, с пришествием GitHub Copilot и код стало писать веселее и тесты для него.
Забавно, вспомнил свою статью 2018 года про это.
Vitaly48
Тесты это классно, но иногда есть расхождения между тем как должно работать, и как на самом деле работает. В тестовой среде может не быть каких то данных, внешние системы заменяется моками, а баги могут быть плавающими и проявляться только под нагрузкой, при наличии увеличенного лага репликации базы данных, или например при параллельном выполнении нескольких потоков. Так же баги могут быть во внешних библиотеках или в самом фреймворке.
Поэтому я не понимаю вашу категоричность в этой фразе
А по поводу тестов, я правильно понимаю что вы после написания тестов пишите код сразу без багов и с первого же раза ваш код проходит написанные вами тесты?
ivankudryavtsev
Какая разница сразу он рабочий или не сразу? Когда он покрыт тестами и я доволен кодом, тогда он и идет в интеграцию. Дебаггер вот мне совершенно не нужен.
Пишите тесты на ситуацию с БД. Вам в описанном вам случае нужен не дебаггер, а трейсер и прочая телеметрия. Есть интеграционные тесты, есть chaosmonkey. Docker открыл дорогу к тестированию на любые фантазии.
Если сторонняя либа без исходников - это история грустная, но нефантомные баги локализуются и воспроизводятся и отправляются вендору и без дебага. Вам зачем знать отчего оно глючит?
Многопоточный код - это отдельная история и больше про квалификацию и опыт, а не отладку в дебаггере.
tema8
Я солидарен с вами в том, что тоже не использую дебаггер, так и не привык. Однако отмечу что ряд коллег ловко использует его как раз в тестах, чтоб понять почему же он не проходит. Так что дебаггер никак не противоречит хорошему покрытому тестами коду, это лишь дело вкуса.
ivankudryavtsev
Так я не отказываю в праве на дебаг, я лишь пишу почему, на мой вкус, он не нужен…
Более того, если бы я научился пользоваться дебаггером за пределами школьного турбопаскаля, может быть у меня было бы другое мнение. Однако, мне он просто не нужен в последние 18 лет…