I'm trying to create a docker container with PHP and Xdebug to use step debugging. I use VSCode and somehow this debugger it's not working.
Apparently the Dockerfile is not been executed when I use docker compose up -d
command. I assume that is because in the file it has a COPY
command to copy a file (called 90-xdebug.ini
) from my project to a specific directory. And after the container is up, I check the directory and the file isn't there... then I have to execute the commands in Dockerfile manually.
Anyways, after installing, I know that the installation worked because the xdebug_info()
function works. But I don't know why VSCode can't debug it.
My OS is Ubuntu 20.04.5 LTS; Dockerfile, docker-compose.yml and 90-xdebug.ini are in project's root.
My Dockerfile:
FROM php:7.4-apache
COPY 90-xdebug.ini "/usr/local/etc/php/conf.d"
RUN pecl install xdebug
RUN docker-php-ext-enable xdebug
90-xdebug.ini:
xdebug.mode=debug
xdebug.discover_client_host=0
xdebug.client_host=host.docker.internal
docker-compose.yml:
services:
php-apache:
container_name: php-apache
image: php:7.4-apache
build:
context: .
dockerfile: Dockerfile
extra_hosts:
- "host.docker.internal:host-gateway"
volumes:
- ./:/var/www/html/
working_dir: /var/www/html/
ports:
- 3003:3003
entrypoint: "php -S 0.0.0.0:3003"
launch.json inside ".vscode" directory:
{
// 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",
"port": 9003
},
{
"name": "Launch currently open script",
"type": "php",
"request": "launch",
"program": "${file}",
"cwd": "${fileDirname}",
"port": 0,
"runtimeArgs": [
"-dxdebug.start_with_request=yes"
],
"env": {
"XDEBUG_MODE": "debug,develop",
"XDEBUG_CONFIG": "client_port=${port}"
}
},
{
"name": "Launch Built-in web server",
"type": "php",
"request": "launch",
"runtimeArgs": [
"-dxdebug.mode=debug",
"-dxdebug.start_with_request=yes",
"-S",
"localhost:0"
],
"program": "",
"cwd": "${workspaceRoot}",
"port": 9003,
"serverReadyAction": {
"pattern": "Development Server \\(http://localhost:([0-9]+)\\) started",
"uriFormat": "http://localhost:%s",
"action": "openExternally"
}
}
]
}
Extra information: this is my program and i've put a break point on "$var = "txt1" " line, but it runs directly towards "xdebug_info()"
<?php
function fprint(string $str):void{
echo $str;
}
$var = "txt1";
fprint($var);
$var = "txt2";
fprint($var);
$var = "txt3";
fprint($var);
// echo $PHP_INI_DIR;
// echo phpinfo();
xdebug_info();
As you say (in a comment) that xdebug_info()
shows that you had an active debugging connection, then that means that the debugger works. What is likely happening here is that:
you don't have any breakpoints set - in which case the debugger never breaks
more likely, that you do have a breakpoint set, but that you don't have a path mapping configured, that maps a path from inside the container (/var/www/html
) to your local project route, which you can refer to with "${workspaceRoot}/html"
. You need to tell VS Code this path mapping by making the following configuration:
"configurations": [
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
"port": 9003,
"pathMappings": {
"/var/www/html": "${workspaceRoot}/html",
}
},
I might not have gotten the exact right paths in this configuration. If you tell Xdebug to make a log file (-dxdebug.log=/tmp/xdebug.log
and -dxdebug.log_level=10
) it will create a log file in your container, where the contents tell you which breakpoint file name is tried to be matched against the files that PHP sees, something like:
[11] [Step Debug] DEBUG: I:
Matching breakpoint '/home/caio/dev/project/html/info.php:1'
against location '/var/www/html/info.php:2'.
If these paths don't match, adjust your path mappings.