Гайд для 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 updatesudo 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 лет…