Debugging your PHP application inside a Docker environment using Xdebug

Introduction

Once our PHP application start growing and the code getting more complex, the debugging part tends to be harder, and for every programming language, we have some tools for that. A good one for PHP is Xdebug, and in this article, I will share with you how to use it in a Docker environment. If you missed the post on how to set up this kind of environment you can check it here.

Let’s rock!

Once our environment is ready, let’s install Xdebug in our PHP container by adding those lines to our PHP-FPM Dockerfile.

# Install xDebug and Redis
RUN docker-php-source extract \  
    && pecl install xdebug \
    && docker-php-ext-enable xdebug \
    && docker-php-source delete

PRO TIP: If you're using PHP 7.2 (like in the code repo), you need to install xdebug-alpha instead of xdebug.

Now, let’s configure Xdebug, and this can be done by creating a xdebug.ini file in the conf.d/ configuration folder.

xdebug.default_enable=1  
xdebug.remote_enable=1  
xdebug.remote_handler=dbgp  
xdebug.remote_port=9001  
xdebug.remote_host=10.254.254.254  
xdebug.remote_autostart=0  
xdebug.remote_connect_back=0  
xdebug.idekey="sublime.xdebug"  
xdebug.remote_log="/tmp/xdebug_log/xdebug.log"  

Here we enable remote Xdebug since technically our IDE/Editor is not in the same server as where the PHP is running (in a Docker container), and for that, we need to specify the IP address of our local machine using the remote_host parameter.

Please note that the remote_port is set to 9001 instead of the default one 9000 since this one is used by PHP-FPM.

PRO TIP: You can get your IP address using ifconfig command or other. In case you’re using Mac OS, Xdebug can’t reconnect to the host (the issue), to get around this issue, you can create an alias of your host machine’s IP address to 10.254.254.254 and set it in the configuration (as shown below). And to do that you can execute this command sudo ifconfig en0 alias 10.254.254.254 255.255.255.0

The idekey is a token that our host machine use to reconnect to the container, we’ll use this key when we configure our IDE.

We set a remote_log temporary just to debug our configuration issues, we can remove it once everything is setup and running well.

IDE/Editor

The final step is to configure whatever we use to write and debug our PHP code, the configuration is almost the same for all editors and here we’ll see how to do it for Sublime Text and PhpStorm.

Sublime Text

First we need to install Xdebug client plugin, after that we need to configure it => Tools > Xdebug > Settings - User

After that, we need to map our host application folder to the application folder in the container. Here is an example of my configuration:

"path_mapping": {
    "/var/www/app/" : "/Users/zakariae/projects/repos/docker-php/app/"
},

Remember the idekey we configured earlier in the xdebug.ini file, we’ll set it here with the port also like this.

"ide_key": "sublime.xdebug",
"port": 9001,

The Tools > Xdebug > Settings - Default menu show the plugin configuration with a description of every parameter.

To start debugging we use the Tools > Xdebug > Start Debugging menu, we can set breakpoints to check the state of our application environment in a given time of the execution. The menu to navigate during the debugging can be found by a right-click when editing a PHP file.

PhpStorm

In case of using PhpStorm, we need only to configure the Xdebug port using the Preferences menu and look for xdebug using the search input.

And to map our host application folder to the application folder in the container we look for the preference using servers filter, and we add a new server by clicking on the + sign and we set whatever we want as a server name, the Host will be the default host for our local application, and the most important part here is to map the application local and container folders.

Finally we set the debugger by Run > Edit Configurations and we add a debugger by clicking on the + sign again and choose PHP Remote Debug, let’s give it a name and choose the server we create earlier, in the ide key we need to use the same key we used in Xdebug configuration sublime.xdebug.

To start debugging we click on the phone icon on the top right.

Browser’s configuration

All we need to do now is to intercept the events sent by Xdebug into our IDE, and this can be done either by setting a cookie or sending each time a parameter with our GET/POST requests, to automate this, there is some browser’s extension that help, for example for Google Chrome we use Xdebug helper, once activated you can start debugging your application as you like, for other browsers please check the extensions list here.

And this is all, happy debugging ;)