XDebug не может подключиться к клиенту из контейнера докеров
У меня есть несколько контейнеров-докеров: php, nginx, mariadb, redis, adminer и я пытаюсь отладить код PHP с помощью PhpStorm и Xdebug.
Хост (ноутбук Lenovo T490):
$ hostname
T490
$ docker -v
Docker version 20.10.5, build 55c4c88
$ docker-compose -v
docker-compose version 1.24.1, build 4667896b
$ cat /etc/lsb-release
DISTRIB_ID=neon
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="KDE neon User Edition 5.21"
$ php -v
PHP 7.4.16 (cli) (built: Mar 5 2021 07:54:20) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.16, Copyright (c), by Zend Technologies
$ lsof -i :9003 | grep LISTEN
java 14868 kane 48u IPv6 401093 0t0 TCP *:9003 (LISTEN)
$ cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 T490
# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.1 foo.pl adm.foo.pl api.foo.pl
Конфигурация PhpStorm 2020.3.3:
Докер-compose.yml
version: "3"
services:
php-7.4:
extra_hosts:
- "host.docker.internal:host-gateway"
build: ./docker-images/php-7.4
image: ap/php:7.4
container_name: foo-php-7.4
environment:
- GITHUB_API_TOKEN=${GITHUB_API_TOKEN}
- XDEBUG_IDEKEY=${XDEBUG_IDEKEY}
volumes:
- ~/.composer-docker/cache:/root/.composer/cache:delegated
- ~/.gitconfig:/root/.gitconfig
- ${WORKSPACE_DIR}:/var/www
- ~/.ssh:/root/ssh:ro
- ./docker/php/conf.d/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
XDebug в DockerFile устанавливается через:
RUN pecl install xdebug \
&& docker-php-ext-enable xdebug
.env
GITHUB_API_TOKEN=
WORKSPACE_DIR=/home/kane/workspace
XDEBUG_IDEKEY=PHPSTORM
COMPOSE_PROJECT_NAME=yii2fpm
COMPOSE_FILE=docker-compose.yml
X_LEGACY_GD_LIB=1
PHP_CGI_PASS=php-7.4:9000
NGINX_PORT=80
NGINX_SSL_PORT=443
DB_PORT=3306
ADMINER_PORT=8182
xdebug.ini
zend_extension=xdebug
[xdebug]
xdebug.mode=develop,debug
xdebug.client_host=172.17.0.1
xdebug.start_with_request = yes
После docker-compose up в контейнере:
# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default T490 0.0.0.0 UG 0 0 0 eth0
172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
# ping T490
PING T490 (127.0.1.1) 56(84) bytes of data.
64 bytes from T490 (127.0.1.1): icmp_seq=1 ttl=64 time=0.057 ms
# ping 172.17.0.1
PING 172.17.0.1 (172.17.0.1) 56(84) bytes of data.
64 bytes from 172.17.0.1: icmp_seq=1 ttl=64 time=0.145 ms
# telnet 172.17.0.1 9003
Trying 172.17.0.1...
# telnet T490 9003
Trying 127.0.1.1...
telnet: Unable to connect to remote host: Connection refused
# php -v
PHP 7.4.16 (cli) (built: Mar 13 2021 02:52:33) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.16, Copyright (c), by Zend Technologies
with Xdebug v3.0.3, Copyright (c) 2002-2021, by Derick Rethans
И когда я перехожу на http://adm.foo.pl/ (с файлом cookie XDEBUG_SESSION:"PHPSTORM"), журнал докеров говорит:
NOTICE: PHP message: Xdebug: [Step Debug] Time-out connecting to debugging client, waited: 200 ms. Tried: 172.17.0.1:9003 (through xdebug.client_host/xdebug.client_port) :-(
После изменения xdebug.ini на:
zend_extension=xdebug
[xdebug]
xdebug.mode=develop,debug
xdebug.discover_client_host = yes
xdebug.start_with_request = yes
он говорит:
NOTICE: PHP message: Xdebug: [Step Debug] Could not connect to debugging client. Tried: 172.18.0.1:9003 (from REMOTE_ADDR HTTP header), localhost:9003 (fallback through xdebug.client_host/xdebug.client_port) :-(
после добавления
extra_host
говорит:
NOTICE: PHP message: Xdebug: [Step Debug] Time-out connecting to debugging client, waited: 200 ms. Tried: host.docker.internal:9003 (through xdebug.client_host/xdebug.client_port) :-(
Пожалуйста помоги :-)
5 ответов
Как жаль ... Обычно я работаю на Centos7, поэтому искал фаервол через
firewall-cmd
вместо
ufw
(в Ubuntu / Debian).
$ sudo ufw allow 9003
Теперь все заработало как надо.
С помощью Docker в Linux вы можете:
- Используйте физический сетевой интерфейс (ens* или eth0 или что-то подобное) IP для подключения к хосту, или
- Используйте этот хак, чтобы иметь возможность использовать
host.docker.internal
:https://github.com/docker/for-linux/issues/264#issuecomment-759737542
Установка
telnet
в контейнере для проверки доступности порта всегда хорошая идея, тот факт, что
172.17.0.1
ответ на пинг не обязательно означает, что это хост.
В моем случае брандмауэр (ufw) в Ubuntu не был причиной: именно Docker без root-прав не позволял XDebug внутри контейнера подключиться к IDE на хосте. XDebug нужен мостовой сетевой интерфейс с именемbr-xxxx
и принадлежит тому же сетевому диапазону, что и контейнер php. Этот мостовой интерфейс невозможно создать в режиме без root (поэтому только интерфейс Dockerdocker0
создано). Другой моей целью было продолжать использоватьhost.docker.internal
в compose.yml (вместо192.168.x.x
для Ethernet или Wi-Fi).
Решение, которое сработало для меня:
- добавлен в сервис php в
compose.yml
extra_hosts:
host.docker.internal: host-gateway
- Добавлено в
docker-php-ext-xdebug.ini
xdebug.client_port=9003
xdebug.client_host=host.docker.internal
- запуск докера с помощью sudo , например
sudo docker compose up -d
Взято отсюда:
Потратив пару часов на решение этой проблемы, я решил поговорить с192.168.x.x
IP-адрес хоста, а не172.17.0.1
. Это сработало.
Точная стоимость дляx.x
можно определить с помощью следующих шагов в Windows 10:
- Пуск -> Командная строка (Запуск от имени администратора)
- запустить
ipconfig | find "IPv4"
команда - использовать значение
192.168...
.
Вот как сейчас выглядит моя конфигурация xdebug:
xdebug.client_host=192.168.1.110
xdebug.client_port="9003"
xdebug.start_upon_error=yes
xdebug.idekey = "PHPStorm"
xdebug.mode=develop,coverage,debug,profile
xdebug.discover_client_host=1
В следующей конфигурации docker-compose.yml у меня было два значения, удаление второго снова начало работать
От
extra_hosts:
- "host.docker.internal:host-gateway"
- "host.docker.internal:127.0.0.1"
К:
extra_hosts:
- "host.docker.internal:host-gateway"
Я не знаю, почему моя конфигурация была такой.