How to set up and use Xdebug for debugging PHP code in the TimeTracker development environment.
Xdebug is installed in the dev Docker stage (see Dockerfile,
inherited by the e2e stage) and provides:
- Step debugging with IDE integration
- Enhanced error reporting and stack traces
- Code coverage analysis
It is off by default: docker/php/xdebug.ini
sets xdebug.mode=off, so there is no runtime overhead. Activate it per run
via the XDEBUG_MODE environment variable:
XDEBUG_MODE=debug # step debugging (IDE)
XDEBUG_MODE=coverage # test coverage (used by make coverage)
make test-debug # runs the test suite with XDEBUG_MODE=debug,developThe production image stage does not include Xdebug at all.
The baked-in settings (docker/php/xdebug.ini):
xdebug.mode=off ; enable via XDEBUG_MODE env var
xdebug.start_with_request=yes ; auto-start once a mode is active
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.discover_client_host=true
xdebug.show_error_trace=1
xdebug.show_exception_trace=1Because start_with_request=yes is set, a session starts automatically for
every request as soon as XDEBUG_MODE=debug is active — no browser cookie or
XDEBUG_SESSION parameter is required (an "Xdebug helper" browser extension
still works if you prefer selective triggering).
To enable debugging for the whole dev container, set the variable on the service, e.g. in a compose override:
services:
app-dev:
environment:
- XDEBUG_MODE=debug,develop- Settings → PHP → Debug: Xdebug port
9003, allow external connections - Settings → PHP → Servers: add a server
- Name:
timetracker-dev - Host:
localhost, Port:8765 - Path mapping: project root →
/var/www/html
- Name:
- Start "Listen for PHP Debug Connections"
Install the "PHP Debug" extension and create .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Listen for Xdebug",
"type": "php",
"request": "launch",
"port": 9003,
"pathMappings": {
"/var/www/html": "${workspaceRoot}"
}
}
]
}- Start your IDE debugger (listen for connections)
- Set breakpoints
- Make sure the container runs with
XDEBUG_MODE=debug(see above) - Open http://localhost:8765 — the session starts automatically
# Debug a console command
docker compose exec -e XDEBUG_MODE=debug app-dev bin/console tt:sync-subtickets
# Debug specific PHPUnit tests
docker compose run --rm -e APP_ENV=test -e XDEBUG_MODE=debug app-dev \
./bin/phpunit --filter=testMethodName
# Or simply: whole suite with Xdebug
make test-debugdocker compose exec app-dev php bin/test-xdebug.phpmake coverage # XDEBUG_MODE=coverage → HTML report in var/coverage/index.html- Xdebug not connecting to IDE
- Is the container actually running with
XDEBUG_MODE=debug? Check withdocker compose exec app-dev php -i | grep xdebug.mode - Check the IDE is listening on port 9003
- Verify
host.docker.internalresolves from the container
- Is the container actually running with
- Breakpoints not hit
- Check the path mapping (
/var/www/html→ project root)
- Check the path mapping (
- Slow tests
- Keep
XDEBUG_MODE=off(the default in allmake test*targets excepttest-debugandcoverage)
- Keep
Enable Xdebug's own log for connection issues (in docker/php/xdebug.ini):
xdebug.log_level=7
xdebug.log=/var/log/xdebug.logdocker compose exec app-dev tail -f /var/log/xdebug.log