loading...

Docker, PHPStorm and Xdebug, The definitive guide

brpaz profile image Bruno Paz Updated on ・4 min read

Docker has changed dramatically the way we develop applications. Thanks to it, it is really easy for everyone to run a complex application with a single command, without having to worry about the inner details like dependencies. These advantages are even greater when working on a team or enterprise context. I still remember being like the first 3 days when I joined my current company, configuring the project and all the related libraries and tools. Docker make it such much easier, faster and consistent.

But everything comes with a price. There is an extra complexity of maintaining all the Docker stuff. Also some things that were very easy in a normal development environment running locally, like debugging your application from your IDE, now requires some extra configuration. And in case of getting Xdebug to work, its not an easy task. I couldn't find a single guide that have all the steps from start to finish. Thats why I decided to write this article. It will guide you to step by step through the process of installing and configuring Xdebug and PHPStorm with a Dockerized Symfony 4 application.

Pre-requisites

  • This was tested on an Ubuntu 18.04 machine with PHPStorm 2018.1.4 and latest versions of Docker and Docker Compose. Some things might work a little different in other Operating Systems.
  • I assume you have a basic Knowledge of Docker, PHP and XDebug.
  • You can clone this repository as base to follow this gude as it contains a basic Symfony Flex application with all the Docker stuff explained in this article included.

Step 1 - Dockerize the application

Of course, to be able to use Xdebug you must install it on your Docker container.
The way to do this, will depend of your base image. I always use alpine based images. I wont enter in detail about how to Dockerize a Symfony application. You can follow along with the Dockerfile included in the demo repository.

Here is the relevant excerpt of the Dockerfile that installs Xdebug:

ARG WITH_XDEBUG=false

RUN if [ $WITH_XDEBUG = "true" ] ; then \
        pecl install xdebug; \
        docker-php-ext-enable xdebug; \
        echo "error_reporting = E_ALL" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini; \
        echo "display_startup_errors = On" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini; \
        echo "display_errors = On" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini; \
        echo "xdebug.remote_enable=1" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini; \
    fi ;

I dont want have to have a separate Dockerfile for development and production, so I have defined a build argument that will tell whether we want to install Xdebug or not.

Then, on my Docker-compose file I have the following definition for my application:

version: "3"

services:

  php:
    build:
      context: .
      args:
        - WITH_XDEBUG=true
    env_file: .env
    volumes:
      - .:/var/www/app:rw

See for the full docker-compose file.

Nothing really fancy about this. The important bit is the "env_file" instruction which tells Compose to load environment variables from a ".env" file, which is the standard way for Symfony 4 applications.

We will use that file to add some required environment variables for Xdebug. If you prefer in you can also add directly to the docker-compose file using the "environment" section.

Environment Variables

We will define the following environment variables:

  • PHP_IDE_CONFIG - This variable defines the server configuration associated with the application. More on this later.
  • XDEBUG_CONFIG - This variable allows to define some Xdebug configurations. The "remote host" is the private ip of your host machine (the one your PHPStorm is running). The "remote_port" is the port that PHPStorm will be listening for incoming Xdebug connections. These two settings allow PHPStorm and Xdebug to communicate. It wont work without this.

We will add them to our ".env" file like this:

PHP_IDE_CONFIG=serverName=symfony-demo
XDEBUG_CONFIG=remote_host=192.168.1.102 remote_port=9001

And thats it in terms of code.

Next lets dig into PHPStorm configurations.

PHPStorm configurations

The first thing you should do is to check your Debug settings. In PHPStorm, go to File -> Settings -> Languages and Frameworks -> PHP > Debug.

Make sure you have the some port that you have configured previously in "XDEBUG_CONFIG" environment variable:

Next, we need to configure a server. This is how PHPStorm will map the file paths in your local system to the ones in your container.

Go to File -> Settings -> Languages and Frameworks -> PHP -> Servers

Give a name to your server. It should match the value you have defined in your "PHP_IDE_CONFIG" environment variable. We will call it "symfony-demo".

The "host" and "port" is how will access your application. In my case is localhost:8888.

And then the "Path mappings".

In the "Project files" section you have to map the root path of your application to the path inside the container. In my case its "/var/www/app".

Click "Apply" to save your configurations.

The last part is to configure the remote debugger of your project.

On the top right, click on "edit configurations":

Click in the green "plus" sign at the top left and select "PHP Remote Debug" from the list.

Now configure it like this:

Make sure you associate it with the previously created "server" definition. Use "PHPSTORM" as idekey.

Your IDE should be now correctly configured. Lets test.

Testing

  • Open "src/Controllers/HelloController.php" and place a breakpoint in the "hello" method.

  • Start your Docker container with

    docker-compose up

  • Then click on "Start Listening for PHP Debug connections" icon on top right corner of PHPStorm.

If everything went well you should see the execution stop at your breakpoint.

And thats it. You should now have a fully configured development environment with Docker and Xdebug integrated with PHPStorm IDE.

If you have any issues or questions feel free to comment bellow or in the GitHub Repository.

Thank you and good debugging ;)

Posted on by:

brpaz profile

Bruno Paz

@brpaz

Web Engineer. Working mostly with PHP, Symfony and Golang. Entusiast about Engineering Best Practices, Continuous Delivery and DevOps. Sports and FC Porto fan!

Discussion

pic
Editor guide
 

Hmm, it seems like it's not working on MacOS. Project start is ok, but no debug. I'l try to find correct solution for mac

 

Ok, I found a correct solution for mac. You should use docker.for.mac.localhost instead 192.168.1.102 in .env file for remote_host. And you must enable DBGp proxy in phpstorm setting. Use IDE key: PHPSTORM, Host: docker.for.mac.localhost.
And I have xDebug configured locally on mac, and use 9002 port for debug instead 9001.

 

Thank you so much! 🙏

 

After waisting a few hours - I think it is also worth mentioning that you must also have xdebug.remote_connect_back set to 0 - otherwise it won't initiate the connection from server php-fpm

 

Awesome article, thanks. Couple of points I came across:
1) Running docker-compose up on the demo rep doesn't "just work". I didn't dig in, just a heads up
2) For any else coming across this as dim as I am - be aware that you must have Php and Xdebug installed locally in order for this to work!

 

Thanks for the article, but I could not test :

For some reason, the nginx container crashes at startup so I cannot test :

docker-compose up
Starting symfony-docker-xdebug-demo_php_1 ... done
Recreating symfony-docker-xdebug-demo_nginx_1 ... done
Attaching to symfony-docker-xdebug-demo_php_1, symfony-docker-xdebug-demo_nginx_1
php_1    | standard_init_linux.go:207: exec user process caused "no such file or directory"
nginx_1  | 2019/03/27 15:35:15 [emerg] 1#1: host not found in upstream "php" in /etc/nginx/conf.d/default.conf:10
nginx_1  | nginx: [emerg] host not found in upstream "php" in /etc/nginx/conf.d/default.conf:10
symfony-docker-xdebug-demo_php_1 exited with code 1
symfony-docker-xdebug-demo_nginx_1 exited with code 1

It seems that docker cannot resolve the php hostname, which is weird because I use a similar configuration for other projects without any issue.

 

Hi ! I followed this guide three times but getting this message in Xdebub :
Waiting for incoming connection with ide key 'PHPSTORM'

The URL i loaded in my browser : localhost:8888/?XDEBUG_SESSION_STA...

Please, i need some help, i don't understand why it's not working...

 

I face the same problem.

 

Ok, in my case, my ip address was different. Please check your IP address.

 

Bom dia Bruno, a fellow portuguese kindly needs your help.. In my job we are running PHPStorm to manage our API that was made with Laravel, and runs many async processes with Laravel Jobs and Events, which makes it practically impossible to debug at certain points.. I have tried to change my queue driver to sync but that results in my jobs not working.. Do you have an idea how to debug my async tasks?? Thanks

 

Hi,
On linux with firewalld enabled, the container hasn't route for host, so it not attach to host port 9000 (xdebug). The route can be add by: 
firewall-cmd --zone=public --add-rich-rule='rule family="ipv4" source address="172.17.0.0/16" accept'

Where 172.17.0.0 is docker container's subnet (check it with ifconfig).

 

I never got into Xdebug thing and a little bit started with that. Then fire nation attacked. I mean i started use docker and i was on zero again.
So thank you for this guide, complete and i hope foolproof (will see when i will do that), i love that :)

 

Nice article but my love is for VSCode so I've written a guide for integrating Xdebug in VSCode for PHP debugging. You can read it here: cloudways.com/blog/php-debug-with-...

 

Nice! I also love VSCode and would really like to use it as my single Editor, but its autocomplete and refactoring features are still very behind of Jetbrains IDEs.

I tried a couple of extensions but none of seem to work consistently.

 

Thanks Bruno! I use VS code but your guide was great help! Just switched my dev environment from vagrant managed VMs to docker containers and It's beautiful :D