Nextcloud PHP debugging with Xdebug in Zed editor
I started to switch from PhpStorm to Zed as IDE recently as Zed is open source and has a much smaller footprint and is more slick than PhpStorm.
One thing that I didn't get running immediately was Xdebug integration, so I did a bit of research and asked Claude for help. Here's a quick writeup of how to get it running.
I have Zed installed as Flatpak on a Debian Trixie host system.
The PHP process runs in a nextcloud-docker-dev Docker container.
Install Zed and configure debugging there
Install Zed: flatpak install flathub dev.zed.Zed
In Zed: open the Extensions view and install PHP.
Configure the debugger:
Create ~/.var/app/dev.zed.Zed/config/zed/debug.json:
[
{
"label": "PHP: Listen to Xdebug",
"adapter": "Xdebug",
"request": "launch",
"port": 9003,
"pathMappings": {
"/var/www/html": "/home/<user>/devel/nextcloud/server",
"/var/www/html/apps-extra": "/home/<user>/devel/nextcloud/server/apps-extra",
"/var/www/html/apps-shared": "/home/<user>/devel/nextcloud/apps-shared"
}
}
]
Add one entry per bind-mounted app directory.
After creating the file, restart Zed.
Inside Zed, select "debugger: start" from command palette and then "PHP: Listen to Xdebug".
Verify Zed is listening. Running ss -tlnp | grep 9003 on the host should show *:9003 with Zed as the process.
Configure Xdebug inside the container
/usr/local/etc/php/conf.d/xdebug.ini:
xdebug.mode = debug
xdebug.idekey = PHPSTORM
xdebug.trace_output_name=trace.%R.%u
xdebug.profiler_output_name=profile.%R.%u
xdebug.output_dir=/shared/xdebug
xdebug.log = /var/log/xdebug.log
xdebug.log_level = 3
; Try to discover the client host, otherwise fall back to the docker host
xdebug.discover_client_host=true
xdebug.client_host=host.docker.internal
; When you cannot specify a trigger, use "xdebug.start_with_request = yes" to autostart debugging for all requests
; https://xdebug.org/docs/all_settings#start_with_request
xdebug.start_with_request = trigger
; Set xdebug.mode trace to use this
; More details at https://derickrethans.nl/flamboyant-flamegraphs.html
xdebug.trace_format=3
xdebug.trace_output_name=xdebug.%R.%u
Apply changes by restarting apache in the container: apache2ctl -k graceful
Notes:
host.docker.internalresolves on Linux Docker only if the container was started with--add-host=host.docker.internal:host-gateway(nextcloud-docker-dev already does this).discover_client_host = truemakes xdebug followX-Forwarded-For- useful behind Nextcloud's dev reverse proxy.
Test xdebug with a PHP command inside the container
Run XDEBUG_SESSION=PHPSTORM php occ status inside the container and check /var/log/xdebug.log.
Install the browser extension
Install Xdebug Helper (Firefox/Chrome). In its preferences, set the IDE Key to PhpStorm. It will set the XDEBUG_SESSION cookie when toggled to Debug.
Click the Xdebug Helper icon in the browser and set it to Debug.
Test Xdebug with browser extension
Load the URL that exercises the code path with the breakpoint. Zed should stop the code exection at the breakpoint.