Goodbye var_dump: How to Properly Configure Xdebug in Docker and VS Code

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

The Nightmare of var_dump() and print_r()

The feeling of staying up all night just to trace a null variable hiding in thousands of lines of code is surely familiar to any PHP developer. The most “traditional” method is still inserting var_dump(); die(); everywhere and hitting F5 until your hand gets tired. If you’re lucky, you find the bug in minutes. If not, you fall into an endless loop of insert – delete – insert.

When I first started, I was also loyal to this manual approach. However, as projects grew and moved to Docker, debugging with the naked eye became a nightmare. I once managed a system with over 20 concurrent containers. At that time, tracing a logic bug through logs took me over 4 hours just to find the right starting point. That was the moment I realized: I had to master Xdebug at all costs.

Xdebug and Docker: Understanding the Rules of the Game

To configure it successfully, you need to master one vital principle. We often mistakenly think VS Code connects to Xdebug. In reality, it’s the opposite: Xdebug is the one that actively reaches out to VS Code.

When a PHP application runs in Docker, Xdebug sends a signal out to the host machine via port 9003. At this point, VS Code acts as a server “waiting” for a connection. Once they catch the same frequency, you can stop the code anywhere (breakpoint), inspect every corner of your variables, and step through line by line like a god. No more guessing; everything is crystal clear.

Hands-on Configuration

Let’s take an example of a simple PHP project running with Docker Compose, with code located in the ./src directory.

Step 1: Modify the Dockerfile

Don’t use a vanilla PHP image. You need to install the Xdebug extension to enable debugging. Here is a standard Dockerfile for a Debian/Ubuntu-based image:

FROM php:8.2-fpm

RUN apt-get update && apt-get install -y \
    git \
    unzip \
    && pecl install xdebug \
    && docker-php-ext-enable xdebug

# Copy custom configuration file into the container
COPY ./docker/php/xdebug.ini /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini

Step 2: The xdebug.ini File – The “Soul” of the Connection

Create an xdebug.ini file with the following content. Pay close attention to the client_host line:

zend_extension=xdebug

[xdebug]
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.log=/tmp/xdebug.log

Tip: host.docker.internal is the keyword that helps the container point back to the host machine on Windows/Mac. On Linux, you might need to add extra_hosts to your docker-compose.yml file to define this keyword.

Step 3: Setting up VS Code (launch.json)

Open the Debug tab in VS Code (shortcut Ctrl+Shift+D) and create a launch.json file with the following content:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for Xdebug",
            "type": "php",
            "request": "launch",
            "port": 9003,
            "pathMappings": {
                "/var/www/html": "${workspaceRoot}/src"
            }
        }
    ]
}

Note: pathMappings is where 90% of developers get it wrong. It helps VS Code map the index.php file at /var/www/html (inside Docker) to the correct file in the src directory on your machine.

Real-world Lessons

When I applied this configuration to real projects, my productivity skyrocketed. I remember most vividly a time I had to handle a logic bug in an API payment loop. Using var_dump, I could never catch the exact moment the $balance variable was incorrectly deducted amidst dozens of nested function calls.

Thanks to Xdebug, I just needed to set a breakpoint and observe the value changing step by step. The result? The bug was in an old line of code from two years ago that no one had noticed. This saved me 40% of my bug-fixing time, allowing me to spend that time grabbing a coffee or optimizing the server.

Advice: Don’t keep xdebug.mode=debug enabled constantly in your development environment as it will slightly slow down the web performance. Only turn it on when you truly need to “inspect” a bug.

Conclusion

Setting up Xdebug in Docker might seem a bit tricky regarding networking at first. However, it is an incredibly profitable investment for your career. Ditch those ugly dump code lines and start debugging professionally today. Happy bug-fixing!

Share: