Reputation: 93
I'm trying to set up php debugging with VSCode and xDebug, but xDebug can't connect to the host. Thus, VSCode doesn't hit any breakpoints either.
When I start the debug listener in VSCode, run a Bash shell in the php-fpm container and try to connect to the host, it fails:
$ docker-compose exec php-fpm bash
root@178ba0224b37:/application# nc -zv 172.20.0.1 9001
172.20.0.1: inverse host lookup failed: Unknown host
(UNKNOWN) [172.20.0.1] 9001 (?) : Connection refused
I'm confused about the IP addresses, because in the Docker settings the Virtual Switch subnet is set to 10.0.75.0
, and the network adapter vEthernet (DockerNAT)
uses the IP 10.0.75.1
. How do the containers get the IP range 172.20.0.x
?
From my desktop I am unable to request the webpage using 172.20.0.1
.
It works fine with 10.0.75.1
, which shows the phpinfo()
as expected, but the breakpoint is not triggered.
phpinfo()
shows xDebug is configured and the settings match what I have in the php-ini-overrides.ini
config.
I've disabled the firewall, tried different IP's, and checked the port and various xDebug, php, docker-compose, and VSCode debug settings.
I've been searching far and wide, but I guess I'm still missing something. My guess is that it has to do with the network connection, but I don't know what else I can change to fix this issue.
Setup
Host is Windows 10 with docker-compose and VSCode.
I got the docker debug-test
directory from https://phpdocker.io/generator
Basically it uses two docker containers: nginx:alpine
and phpdocker/php-fpm
My VSCode workspace looks like this:
(The readme files come from the phpdocker.io generator and contain some basic Docker info)
index.php
contents:
<?php
phpinfo(); // <-- VSCode breakpoint here
echo 'hello there';
?>
The IP addresses for the containers:
/debug-test-php-fpm - 172.20.0.3
/debug-test-webserver - 172.20.0.2
$_SERVER['REMOTE_ADDR']: 172.20.0.1 <- the host?
Configs and logs
launch.json
contents:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Listen for XDebug",
"type": "php",
"request": "launch",
"pathMappings": {
"/application/public": "${workspaceRoot}/public"
},
"log": true,
"port": 9001,
"xdebugSettings": {
"max_data": 65535,
"show_hidden": 1,
"max_children": 100,
"max_depth": 5
}
},
{
"name": "Launch currently open script",
"type": "php",
"request": "launch",
"program": "${file}",
"cwd": "${fileDirname}",
"port": 9001
}
]
}
docker-compose.yml
contents:
###############################################################################
# Generated on phpdocker.io #
###############################################################################
version: "3.1"
services:
webserver:
image: nginx:alpine
container_name: debug-test-webserver
working_dir: /application
volumes:
- .:/application
- ./phpdocker/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
ports:
- "8000:80"
php-fpm:
build: phpdocker/php-fpm
container_name: debug-test-php-fpm
working_dir: /application
volumes:
- .:/application
- ./phpdocker/php-fpm/php-ini-overrides.ini:/etc/php/7.2/fpm/conf.d/99-overrides.ini
php-ini-overrides.ini
contents:
upload_max_filesize = 100M
post_max_size = 108M
# added for debugging with Docker and VSCode
xdebug.remote_enable=1
xdebug.remote_connect_back=On
xdebug.remote_autostart=1
# xdebug.remote_host=172.20.0.1 # using remote_connect_back instead, which should work for any IP
xdebug.remote_connect_back=1
xdebug.remote_port=9001
xdebug.profiler_enable=0
xdebug.var_display_max_depth = 5
xdebug.var_display_max_children = 256
xdebug.var_display_max_data = 1024
xdebug.remote_log = /application/xdebug.log
xdebug.idekey = VSCODE
xdebug.log
contents after one visit to the page:
Log opened at 2019-01-30 12:37:39
I: Checking remote connect back address.
I: Checking header 'HTTP_X_FORWARDED_FOR'.
I: Checking header 'REMOTE_ADDR'.
I: Remote address found, connecting to 172.20.0.1:9001.
W: Creating socket for '172.20.0.1:9001', poll success, but error: Operation now in progress (29).
E: Could not connect to client. :-(
Log closed at 2019-01-30 12:37:39
Log opened at 2019-01-30 12:37:39
I: Checking remote connect back address.
I: Checking header 'HTTP_X_FORWARDED_FOR'.
I: Checking header 'REMOTE_ADDR'.
I: Remote address found, connecting to 172.20.0.1:9001.
W: Creating socket for '172.20.0.1:9001', poll success, but error: Operation now in progress (29).
E: Could not connect to client. :-(
Log closed at 2019-01-30 12:37:39
This is no paste error, it actually logs the request two times for some reason.
Debug console in VSCode after starting the debug listener:
<- launchResponse
Response {
seq: 0,
type: 'response',
request_seq: 2,
command: 'launch',
success: true }
Any thoughts? I'm lost.. Perhaps it has to do with the DockerNAT setup?
Sorry for the long post. I'm still new to Docker, I hope this has all the info needed.
See my answer below.
Upvotes: 2
Views: 4538
Reputation: 93
After some coding I stumbled upon the solution.
The IP address in the php debug settings was incorrect. Since my system has VPN connections, multiple ethernet adapters, multiple virtual switches, and multiple virtual machines, it's a bit tricky to find out what's used where.
I discovered the IP by accident when I ran netstat on the php container during a request:
$ docker-compose ps --services
php
app
$ docker-compose exec php sh
/var/www/html # netstat
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 08674b3fd785:58060 192.168.137.12:http TIME_WAIT
tcp 0 0 08674b3fd785:58062 192.168.137.12:http TIME_WAIT
[...]
udp 0 0 08874b3cd785:35298 192.168.65.1:domain ESTABLISHED
I tried the 192.168.65.1
IP first, but that didn't work.
The 192.168.137.12
is the IP of a Hyper-V Virtual Machine that the php script connects to. Apparently the php container can connect to that, so maybe then it could also connect to the Windows adapter that's bound to that virtual switch, in other words: 192.168.137.1
.
Adding this to the xDebug settings solved the problem:
xdebug.remote_host = 192.168.137.1
.
Upvotes: 5