Install and configure Xdebug 3 in a docker container and integrate step debugging with PhpStorm

Syed Sirajul Islam Anik
6 min readAug 10, 2021

--

Image from: Wikimedia

Installation

To install xdebug we can add the following line in our dockerfile.

RUN pecl install xdebug

The above instruction will install the xdebug inside our docker container.

To enable xdebug in our container we can simply put the following instruction in our dockerfile.

RUN docker-php-ext-enable xdebug

The above instruction will enable xdebug inside our container.

Now, if we boot up our container, and execute the phpinfo() method, and search for the term Xdebug on the page, we will get to see that xdebug is installed inside our PHP Container.

xdebug module is installed inside our container

For now, ignore the red mark zone. We’ll configure it later. But phpinfo() should show the xdebug section on the page.

Configuration

With Xdebug 3, you can enable/disable different features. If you’re certain that you want to enable specific features, you can just grab the suitable configuration and dump that in the configuration directory. You can find the directory from your phpinfo() dump. In the following image, the red rectangular box shows the path where we should place additional configurations.

Shows the directory to put additional configuration

But, I have thought to configure it in a way that I can enable or disable features when booting up the container. So, I have changed my Dockerfile in this way. The following gist shows how I configured Xdebug.

Explanation

In the above, there are five ini files. the xdebug-default.ini contains the basic configuration. xdebug-off.ini to disable the xdebug. And the remain ini files are for different types of features.

I have all my ini files in the project_root/docker/php directory. And the directory also contains the PHP’s Dockerfile.

Firstly, in the Dockerfile I have copied all the configuration files inside the container’s /home/xdebug directory.

COPY ./docker/php/xdebug-debug.ini /home/xdebug/xdebug-debug.ini
COPY ./docker/php/xdebug-default.ini /home/xdebug/xdebug-default.ini
COPY ./docker/php/xdebug-off.ini /home/xdebug/xdebug-off.ini
COPY ./docker/php/xdebug-profile.ini /home/xdebug/xdebug-profile.ini
COPY ./docker/php/xdebug-trace.ini /home/xdebug/xdebug-trace.ini

As I want to enable/disable the features when booting the containers, I have set a few arguments so that they can be passed during the build process

ARG XDEBUG_MODES
ARG REMOTE_HOST="host.docker.internal"
ARG REMOTE_PORT=9003
ARG IDE_KEY="docker"
ENV MODES=$XDEBUG_MODES
ENV CLIENT_HOST=$REMOTE_HOST
ENV CLIENT_PORT=$REMOTE_PORT
ENV IDEKEY=$IDE_KEY

The XDEBUG_MODES argument determines the mode I want to enable or disable. The REMOTE_HOST is set to host.docker.internal if I want to enable step debugging. REMOTE_PORT is also for the port for step debugging. The IDE_KEY is set to docker by default and is also for step debugging. Later we’ll see how to integrate with PhpStorm to do the step debugging.

Next, the arguments are set to environment variables so that they are available inside the container.

In the next step on Dockerfile, we’re defining and setting the entry point for the container.

COPY ./docker/php/fpm-entrypoint.sh /home/fpm-entrypoint
RUN chmod +x /home/fpm-entrypoint
# ...
ENTRYPOINT ["/home/fpm-entrypoint"]

Next, in the fpm-entrypoint.sh entry point file, we’re pushing the ini files to the configuration directory based on the modes we set during the build time.

And, finally in our docker-compose.yml file, [go through the comments too]

version: '3.8'services:
php:
build:
context: .
dockerfile: ./docker/php/Dockerfile
args:
# Available [trace|debug|profile].
# Use Comma separated available values
# for multiple mode
# Use "off" to disable xdebug
- XDEBUG_MODES=debug,trace
#- XDEBUG_MODES=off
# Set the following values to overwrite the
# existing settings.
# Uncomment the following line and change value.
- REMOTE_HOST=host.docker.internal # Host machine IP
- REMOTE_PORT=9003 # IDE/Editor's listener port
- IDE_KEY=docker # IDE's filter/listener key
volumes:
- .:/var/www/html
# Use sudo if required.
# RUN: mkdir -p /tmp/xdebug
# RUN: chmod -R 777 /tmp/xdebug
#
Log files will be written in this directory
- /tmp/xdebug:/tmp/xdebug

In the above docker-compose.yml snippet, we’ve mounted the host machine’s /tmp/xdebug to container’s /tmp/xdebug. In the xdebug-default.ini file, we’ve set the default output-dir to /tmp/xdebug inside the container. As the files will grow over time, in each boot, it will clean up the /tmp directory. That’s why we have mounted the host machine’s /tmp directory. Read the comments of the docker-compose.yml file. The REMOTE_HOST is set to host.docker.internal for Linux. You may use docker.for.mac.localhost on Mac.

Now, if you build and run the container, and executephpinfo() from your PHP file, then you’ll get to see that the xdebug is installed in your container and the enabled features are like below.

xdebug is enabled and features are enabled

Integrate step debugging with PhpStorm

Open your PhpStorm’s preferences. And search for the term debug. Next, in the Language & Frameworks > PHP > Debug, you’ll find debug port: 9000, 9003 in Xdebug section. This 9003 is the port we used in the REMOTE_PORT argument in our Dockerfile and docker-compose.yml file.

Next, Go to the Languages & Frameworks > PHP > Servers, Click on the plus button, add a name to the server. Set the host to localhost and port to 80. The debugger is set to Xdebug. Tick the Use path mappings. It’ll show you the project directory. Click on the right side under the “Absolute path on the server” and set it to /var/www/html. This /var/www/html directory is where the sources reside in the webserver. If yours is in a different directory, use that path here. Next, save the configuration.

Next from the top menu bar, go to the Run > Edit Configuration and this shows a popup like below. Then click on the PLUS(+) sign on the top left corner.

Search through and click on the PHP Remote Debug. Set a name. Tick mark on the “Filter debug connection by IDE Key”. Set the server from the dropdown to the one you’ve set in the previous server setup step. In the IDE Key set it to that one you’ve set in your Dockerfile or docker-compose.yml file. We have previously set it to docker. Save it and exit the popup.

Next, set a breakpoint. In my project, have set in the public/index.php. After that, go to the Run > Debug menu. It’ll show a popup. Click on the name you’ve set for the PHP Remote Debugger. docker is the name in my case in the following image.

Clicking in the debugger will show the toolbar like the following.

And now, if you reload the page from the browser, it’ll then pause the execution at the breakpoint.

Next, it’s up to you how you want to debug your code. The term you will see

  • Step into — Go inside the function and check how it works.
  • Step over — Don’t dive into the function, just execute the function.
  • Step out — Get out of the function. You possibly used step into, now continue further execution without debugging each line and go back to the caller.

Hope this helps setting up and configure the Xdebug in a docker container and integrating with PhpStorm.

Happy coding. ❤

--

--

Syed Sirajul Islam Anik

software engineer with "Senior" tag | procrastinator | programmer | !polyglot | What else 🙄 — Open to Remote