Задать вопрос
Ответы пользователя по тегу Docker
  • Как подключиться к Xdebug запущенному в Docker контейнере на удаленной машине?

    voskobovich
    @voskobovich Автор вопроса
    PHP Developer | 8+ years exp.
    Вот развернутый ответ на мой вопрос.

    Рассмотрим ситуацию со стороны удаленного сервера на котором запущен докер контейнер.
    Докер уже позаботился о бОльшей части проблемы и сделал все роуты так, что ты из контейнера можно было пинговать интерфейс eth0, через который должен поступать интернет на серверную машину. Мало того, из контейнера можно пинговать любой хост на докер-хосте, кроме 127.0.0.1 самого хоста - по вполне понятным причинам (127.0.0.1 из контейнера будет lo интерфейс самого контейнера).
    Допустим IP на eth0 вашего хоста 10.45.6.87. То есть пинг из докер контейнера на 10.45.6.87 должен проходить успешно.
    А раз eth0 это выход во внешний мир, значит можно xdebug`у сказать, что клиент будет на хосту 10.45.6.87 порт 9000, пусть там его ждет. Мы же потом сделаем туда SSH тунель.

    Создаем тунель.
    Пробрасываем удаленный порт через SSH-тунель на локальную машину
    ssh -R 9000:localhost:9000 user@server.com
    и рассчитываем на то, что в итоге бинд на удаленной стороне будет выглядеть так
    10.45.6.87:9000 => 127.0.0.1:9000
    но мы сильно ошибаемся :)
    И эта ошибка стоит нам кучи времени.

    Давайте посмотрим что нам скажет netstat -plnt.
    А сказать он должен, что после запуска тунеля, на удаленной машине мы имеем бинд на
    127.0.0.1:9000, а не 10.45.6.87:9000 как ожидали.
    То есть, получается, что xdebug ждет клиента на 10.45.6.87:9000, а после открытия тунеля клиент оказывается на 127.0.0.1:9000.
    Беда в том, что забиндить клиента мы можем только на локальный хост.
    Так написано в доке man ssh.

    Из контейнера мы 127.0.0.1:9000 докер-хоста увидеть не можем, а значит остается только сделать роутинг пакетов с 10.45.6.87:9000 на 127.0.0.1:9000 внутри удаленной машины.
    Сделать это можно множеством способом, в том числе и iptables. Лично я сделал еще один SSH тунель внутри своего сервера вот так:

    1. В конфигах xdebug указываем
    xdebug.remote_port = 9001
    xdebuh.remote_host = 10.45.6.87

    2. На свою локальную машину через тунель с виртуалки прокидываем порт 9000.
    ssh -R 9000:127.0.0.1:9000 user@server.com
    3. На локальной машине создаем тунель с порта 9000 на 9001
    ssh -g -L 9001:localhost:9000 -f -N 127.0.0.1
    Вот и все.

    Но стоит учесть, что это решение рассчитано только на одного разработчика и полно костылей.
    Так что через пару дней после понятия проблемы я поднял на том же сервере OpenVPN сервер в докере и проблема отпала сама собой.
    Поясняю. VPN создает виртуальную локальную сеть. Моя локальная машина и моя виртуалка которая находится на серверах хостинг-провайдера оказывается в одной локальной сети. А раз так. В таком случае, я могу из docker-контейнера запущеном на виртуалке пинговать свою локальную машину. Значит Xdebug будет подключаться сразу к моей локальной машине без всяких пробросов и костылей.

    При таком раскладе можно настроить Xdebug двумя способами.
    Первый.
    Xdebug будет стучаться на конкретный IP.
    xdebug.remote_port = 9000
    xdebug.remote_host = <IP локальной машины>

    Это полезно когда вы один разработчик на проекте и нужно отлаживать консольные скрипты.

    Второй.
    Xdebug будет стучаться на IP с которого пришел запрос.
    xdebug.remote_connect_back=1
    xdebug.remote_port = 9000

    Удобно, когда работает команда разработчиков, но не удобен когда нужно отладить консольный скрипт. При запуске скрипта в консоли нужно передавать Xdebug`у IP локальной машины разработчика, чтобы он знал куда отдавать дебаг-логи.
    Ответ написан
    1 комментарий