Context
I have a problem with my PHP website. To solve it, I want to step through the code. I am on a Windows machine using VSC as IDE. PHP runs in a docker container in parallel to an nginx container.
The Problem
I don’t know how to connect my VSC Debugger with the PHP runtime in the docker container.
I installed/enabled Xdebug and added a launch.json but the VSC Debugger does not react on page requests.
More details on what I tried
Xdebug seems to work. At least php -v
(in the php container) returns
PHP 8.2.26 (cli) (built: Nov 21 2024 17:59:18) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.26, Copyright (c) Zend Technologies
with Xdebug v3.4.0, Copyright (c) 2002-2024, by Derick Rethans
My xdebug.ini config is:
zend_extension=xdebug
xdebug.mode = debug
xdebug.start_with_request = yes
xdebug.client_host=host.docker.internal
My launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Local docker Xdebug",
"type": "php",
"request": "launch",
"hostname": "localhost",
"port": 9003,
"stopOnEntry": true,
"pathMappings": {
"/var/www/amc/plattform": "${workspaceFolder}\amc"
}
}
]
}
I then run ‘Local docker Xdebug’ and can see that the port is listening.
When I do a request, the page comes up, but the debugger does not connect/stop.
Any idea what is missing?
Update
Thanks to the great comments below I added a page with xdebug_info();
and enabled xdebug logging.
I get:
[Step Debug] Time-out connecting to debugging client, waited: 200 ms. Tried: host.docker.internal:9003 (through xdebug.client_host/xdebug.client_port).
So my container can’t connect to the host port. This is not the first time I want a container to connect to a host port. I am even doing this successfully in another container of the same docker compose file.
Inspired by this SO answer I added
extra_hosts:
- "host.docker.internal:host-gateway"
Still not lucky.
I don’t think that this is the way to go but I also tried to add 9003:9003 to the published ports of the container. I was surprised as the error was gone. Unfortunately VSC still did not react.
The info page showed
Debugger Active
Connected Client host.docker.internal:9003
Looked positiv, but this is independant of the VSC Debugger. So if the Debugger is not listening, the info page still tells me “Debugger: Active” (I guess because my docker port publishing opens that port to pipe it into the container). Seems like xdebug only checks for the open port and not if a real debgger is listening on the other end.
The xdebug.log shows
[7] Log opened at 2024-12-02 22:04:21.868029
[7] [Config] WARN: Not setting up control socket with default value due to unavailable 'tsc' clock
[7] [Step Debug] INFO: Connecting to configured address/port: host.docker.internal:9003.
[7] [Step Debug] INFO: Connected to debugging client: host.docker.internal:9003 (through xdebug.client_host/xdebug.client_port).
[7] [Step Debug] -> <init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" fileuri="file:///var/www/amc/plattform/public_html/phpinfo-192837465.php" language="PHP" xdebug:language_version="8.2.26" protocol_version="1.0" appid="7"><engine version="3.4.0"><![CDATA[Xdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[https://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2024 by Derick Rethans]]></copyright></init>
[7] [Step Debug] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" status="stopping" reason="ok"></response>
[7] Log closed at 2024-12-02 22:04:21.893973
Any ideas left what I can try?
8
The VSC debugger port was listening on the loopback interface (tried both localhost and 127.0.0.1).
I analyzed the difference to another container->host connection in the same docker compose and found, that the connection that worked, listened on 0.0.0.0:port (0.0.0.0 means listen on all network interfaces).
After simply removing the "hostname"
parameter from my launch.json, xdebug was able to connect.
{
"version": "0.2.0",
"configurations": [
{
"name": "Local docker Xdebug",
"type": "php",
"request": "launch",
// "hostname": "localhost", <= without this, the debugger listens on 0.0.0.0
"port": 9003,
"stopOnEntry": true,
"pathMappings": {
"/var/www/amc/plattform": "${workspaceFolder}/amc"
}
}
]
}