Unable to get Xdebug 3 working with Docker
Asked Answered
U

0

0

So, after spending several days of browsing unsuccessfully trying to figure out why upgrading to Xdebug 3 seems to only partially work with my Dockerized Laravel project, here I am. I've closely followed the upgrade guide and official documentation, other recent posts here, and am still completely befuddled as to why the debugger won't stop at breakpoints unless I manually pass in config options to run an Artisan command (more on this a bit below). Everything worked without issue with Xdebug 2.

Below are (what I think are) the relevant portions of config files/outputs. Yes, I realize the same configs are set multiple times, which is a result of trying many different locations to set these options.

docker-compose.yml

php:
    build:
      context: .
      dockerfile: php.dockerfile
    container_name: php
    environment:
      XDEBUG_CONFIG: client_host=host.docker.internal client_port=9001 mode=debug start_with_request=yes
      XDEBUG_MODE: debug
    volumes:
      - ./src:/var/www/html:delegated
    ports:
      - "9000:9000"
    networks:
      - v2

php.dockerfile

FROM php:8.0-fpm

WORKDIR /var/www/html

RUN docker-php-ext-install pdo pdo_mysql bcmath \
  && pecl install -f xdebug-3.0.1 \
  && echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" >> /usr/local/etc/php/conf.d/xdebug.ini;

My host (Windows) php.ini if relevant

zend_extension=C:\xampp\php\ext\php_xdebug-3.0.1-8.0-vs16-x86_64.dll
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_port=9001
xdebug.idekey=VSCODE

launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
            "port": 9001,
            "pathMappings": {
                "/var/www/html": "${workspaceFolder}/src"
            },
            "xdebugSettings": {
                "max_data": 65535,
                "show_hidden": 1,
                "max_children": 100,
                "max_depth": 5
            },
        }
    ]
}

The Xdebug section of php -i output (removed deprecated options)

Feature => Enabled/Disabled
Development Aids => ✘ disabled
Coverage => ✘ disabled
GC Stats => ✘ disabled
Profiler => ✘ disabled
Step Debugger => ✔ enabled
Tracing => ✘ disabled

Debugger => enabled
IDE Key =>  

Directive => Local Value => Master Value
xdebug.cli_color => 0 => 0
xdebug.client_discovery_header => no value => no value
xdebug.client_host => host.docker.internal => localhost
xdebug.client_port => 9001 => 9003
xdebug.cloud_id => no value => no value
xdebug.collect_assignments => Off => Off
xdebug.collect_return => Off => Off
xdebug.connect_timeout_ms => 200 => 200
xdebug.discover_client_host => Off => Off
xdebug.dump.COOKIE => no value => no value
xdebug.dump.ENV => no value => no value
xdebug.dump.FILES => no value => no value
xdebug.dump.GET => no value => no value
xdebug.dump.POST => no value => no value
xdebug.dump.REQUEST => no value => no value
xdebug.dump.SERVER => no value => no value
xdebug.dump.SESSION => no value => no value
xdebug.dump_globals => On => On
xdebug.dump_once => On => On
xdebug.dump_undefined => Off => Off
xdebug.file_link_format => no value => no value
xdebug.filename_format => no value => no value
xdebug.force_display_errors => Off => Off
xdebug.force_error_reporting => 0 => 0
xdebug.gc_stats_output_name => gcstats.%p => gcstats.%p
xdebug.halt_level => 0 => 0
xdebug.idekey => no value => no value
xdebug.log => no value => no value
xdebug.log_level => 7 => 7
xdebug.max_nesting_level => 256 => 256
xdebug.max_stack_frames => -1 => -1
xdebug.mode => develop => develop
xdebug.output_dir => /tmp => /tmp
xdebug.profiler_append => Off => Off
xdebug.profiler_output_name => cachegrind.out.%p => cachegrind.out.%p
xdebug.scream => Off => Off
xdebug.show_error_trace => Off => Off
xdebug.show_exception_trace => Off => Off
xdebug.show_local_vars => Off => Off
xdebug.start_upon_error => default => default
xdebug.start_with_request => default => default
xdebug.trace_format => 0 => 0
xdebug.trace_options => 0 => 0
xdebug.trigger_value => no value => no value
xdebug.var_display_max_children => 128 => 128
xdebug.var_display_max_data => 512 => 512
xdebug.var_display_max_depth => 3 => 3

Plus under Additional modules

XDEBUG_MODE => debug
XDEBUG_CONFIG => client_host=host.docker.internal client_port=9001 mode=debug start_with_request=yes
...
$_SERVER['XDEBUG_MODE'] => debug
$_SERVER['XDEBUG_CONFIG'] => client_host=host.docker.internal client_port=9001 mode=debug start_with_request=yes
...
$_ENV['XDEBUG_MODE'] => debug
$_ENV['XDEBUG_CONFIG'] => client_host=host.docker.internal client_port=9001 mode=debug start_with_request=yes

As I mentioned, running the options as flags on the CLI directly does respect the breakpoints I set -- that is, bashing into the php container and then running php -dxdebug.mode=debug -dxdebug.start_with_request=yes -dxdebug.client_port=9001 -dxdebug.client_host=127.0.0.1 artisan some:command works with the debugger just fine.

Apologies for the length and for the file dump, but I'm truly lost at this point so any pointers would be greatly appreciated!

EDIT: Looks like whatever issue I had was fixed in Xdebug 3.0.2. Thanks to LazyOne for the help!

Ulphi answered 12/1, 2021 at 4:7 Comment(12)
CLI and your web server may be using different php.ini files (common these days on Linux and Mac). You can see what config files are parsed at the top of php_info() output. That's why you need to see at Xdebug info in a same way as you are trying to debug. P.S. You have && echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" >> /usr/local/etc/php/conf.d/xdebug.ini; -- why not put the rest of Xdebug config in the same manner instead of XDEBUG_CONFIG: client_host=host..... Anyway: try it as see how it goes.Grundyism
I also suggest to enable and collect an Xdebug log and see what it will have to say: where it tries to connect to (if at all) and what the response is. In case if log is empty/no file created: 1) Xdebug is not even trying to debug (misconfig or does not see "debug me" flag) 2) File access permissions 3) Bad path (e.g. /tmp/ on Ubuntu will be virtualized (per process?), better use /var/log/... sort of paths 4) SELinux or alike (which is unlikely to be the case for Docker images). P.P.S. Xdebug 3.0.2 is already available.Grundyism
BTW -- your php -i shows xdebug.start_with_request => default .. while it is expected to be yes. So something does not add up somewhere. Definitely try writing Xdebug config in a file instead of ENV. BTW, you can store your xdebug.ini locally and copy it over (don't know if this is applicable for your images, but anyway: RUN pecl install xdebug && docker-php-ext-enable xdebug COPY ./ini/* /usr/local/etc/php/conf.d/Grundyism
Thanks for the comments! php_info() output is the same as php -i as far as I can tell.Ulphi
I actually did try the Xdebug config in the dockerfile as you suggested, but it didn't work (despite a clean build):Ulphi
what I had was RUN docker-php-ext-install pdo pdo_mysql bcmath \ && pecl install -f xdebug-3.0.1 \ && echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" >> /usr/local/etc/php/conf.d/xdebug.ini \ && echo "client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/xdebug.ini \ && echo "client_port=9001" >> /usr/local/etc/php/conf.d/xdebug.ini \ && echo "mode=debug" >> /usr/local/etc/php/conf.d/xdebug.ini \ && echo "start_with_request=yes" >> /usr/local/etc/php/conf.d/xdebug.ini;Ulphi
Wouldn't there be an issue copying my host PHP config to the container's since I'm on Windows and the container runs Ubuntu? Or are you suggesting specifying just the relevant xdebug configs in a local ini file and then appending the contents to something in the container?Ulphi
Okay, it seems that upgrading to 3.0.2 did the trick! No idea which of the fixes on the updates page did the trick, but thanks so much for the help!Ulphi
Yes, specify whatever is needed for the project in xdebug.ini, keep it local (so it's easy to edit etc) and copy the file into the image on build (instead of making it dynamically via multiple echo statements). May not work if you making the Xdebug extension name dynamically echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" and not via docker-php-ext-enable xdebug. Anyway: do whatever is needed/can be done to get xdebug.start_with_request => yesGrundyism
Well, FWIW xdebug.start_with_request is still set to default but it seems to be working now?Ulphi
As long as it works... BTW: 3.0.2 has some changes in how some values are treated, start_with_request in particular (bugs.xdebug.org/bug_view_page.php?bug_id=00001925), could be related.Grundyism
Yup, saw that and didn't think it applied at the time but in retrospect that seems likely.Ulphi

© 2022 - 2024 — McMap. All rights reserved.