Задать вопрос
  • Как подключиться к 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 комментарий
  • PHP, Yii2 и PostgreSQL. Как сделать поддержку временных зон для юзеров?

    voskobovich
    @voskobovich Автор вопроса
    PHP Developer | 8+ years exp.
    Вот тезисно ответы на мой вопрос
    1. В бд хранить даты нужно в UTC
    2. Yii2 Formatter умеет из коробки **при выводе** учитывать таймзону. Настраиваешь таймзону, передает в него время в UTC и он сам все сдалет за тебя.
    3. Yii2 Date Validator умеет из коробки **при записи** даты в атрибут модели конвертировать ее обратно в UTC и отдавать в указанный в настроках валидатора атрибут модели, чтобы дальше оперировать даными опять же в UTC.
    4. После логина юзера нужно именить у форматтера timeZone на указанную в профиле залогиненого юзера. Пока юзер не залогинен - работаем в UTC.
    5. В UTC нужно перевести ОС, БД и PHP. Соответственно
    date_default_timezone_set('UTC'); или в php.ini
    6. Формат времени лучше не перекладывать на базу, так как переезд на другую базу или взятие данных из кэша все сломают.
    Ответ написан
    Комментировать
  • После перехода на Yii2 сильно просела бд?

    voskobovich
    @voskobovich
    PHP Developer | 8+ years exp.
    Если в приложении использовалась жадная загрузка и за счет нее ускорялось получение данных из бд, то стоит учесть, что в Yii2 логика совсем другая на этот счет.
    В Yii1 использовались JOIN, а в Yii2 этого нет и жадная загрузка в некоторых случаях может даже ухудшить ситуацию. На этот счет лучше почитать www.yiiframework.com/doc-2.0/guide-db-active-recor...
    Ответ написан
    Комментировать
  • Как построить логику создания изображений на лету в распределенной системе?

    voskobovich
    @voskobovich Автор вопроса
    PHP Developer | 8+ years exp.
    В итоге я решил пойти третим путем.
    Имя картинки - это base64 строка в которой записан путь к оригиналу и контрольные суммы для проверки корректнсти данных.
    Полет нормальный, решение мне нравится)
    Ответ написан
    Комментировать
  • Как в phpstorm "php" > нажатие клавиши > ""?

    voskobovich
    @voskobovich
    PHP Developer | 8+ years exp.
    Settings => Live Templates => Жмакаешь на плюсик (создать новый шаблон)

    Для примера посмотри другие шаблоны по PHP.
    Ответ написан
  • Как отобразить дерево каталогов проекта в PhpStorm?

    voskobovich
    @voskobovich
    PHP Developer | 8+ years exp.
    А ты уверен что у тебя файлы в папках?
    Папка Project у тебя открыта... там отображается текущая структура проекта как она есть.
    Или ты что-то клацал?

    Как вариант решения - удали проект. Создай заново.
    Ответ написан
    Комментировать