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:
json [ { "label": "PHP: Listen to Xdebug", "adapter": "Xdebug", "request": "launch", "port": 9003, "pathMappings": { "/var/www/html": "/home/<you>/devel/nextcloud/server", "/var/www/html/apps-shared": "/home/<you>/devel/nextcloud/apps-shared" } } ]Add one entry per bind-mounted app directory. Check the mounts with docker inspect --format '{{json .Mounts}}' | jq. Restart Zed. - Restart Zed
- Select "debugger: start" from command palette and then "PHP: Listen to Xdebug"
- Create ~/.var/app/dev.zed.Zed/config/zed/debug.json:
- Verify Zed is listening. Running
ss -tlnp | grep 9003on the host should show*:9003with 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
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.
Apply changes by restarting apache in the container: apache2ctl -k graceful
Test xdebug with a PHP command inside the container
- Run
XDEBUG_SESSION=PHPSTORM php occ statusinside the container - 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_SESSIONcookie when toggled to Debug. - Click the Xdebug Helper icon 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.