This tutorial is a direct add-on to our previous blog post: Docker for Magento 2 Development. You will need to follow that tut before you are able to use Xdebug in your local Magento 2 development environment.
Docker + Xdebug + Magento 2 = Awesome
Ok, here's an analogy for you. Xdebug is to the PHP developer as Robin is to Batman. In this Magento 2 developer tut, we teach you how to add Xdebug to your development flow. In my opinion, this is the most important part of your development environment. Without it, the process of writing code is slower and visibility into the way the code works is limited. In fact, I can easily say that Xdebug is largely responsible for my career success and general Magento skill level. Why? Xdebug allows me to walk through every step of code execution which makes it much easier to understand the Magento architecture. In short, I absolutely love Xdebug.
Before we get started, I should clarify that the scope of this tutorial involves activating and preparing Xdebug to run. However, we do not provide instructions on how to configure your specific IDE to accept Xdebug connections. When I make the follow up video to accompany this written tutorial, I will also walk you through configuring PHPStorm to work with Xdebug and do a full demo.
What is Xdebug?
Xdebug is a low-level PHP debugger that can provide a wealth of real-time information during code execution. It can be used from the command line during script execution and from the browser during page load. With Xdebug, a developer can pause code execution, evaluate different scenarios, see real-time data stored inside of variables, and much, much more.
Install Xdebug In Your Virtual Machine
Adding Xdebug to your local Magento 2 development environment is going to be a piece of cake. It's actually already included in the Docker image for the web service. We only need to configure it and then create a network loopback. I'll explain that down the page a little.
Add Configuration To docker-compose.yml
In this first step, we simply add some environment variables to our docker-compose.yml file. A short explanation/clarification here. You might notice that my php.xdebug.idekey setting is set to PHPSTORM. You do not need PHPStorm for this to work, although, I strongly recommend it. You can make the IDE key setting anything you would like and just make sure that the software of your choice is aware of your IDE key. Additionally, port 9000 is the default port for Xdebug. However, you can change it to use any port you'd like. Again, just make sure your IDE is listening on that port.
- Copy the highlighted lines below into your docker-compose.yml file.
version: '3' services: web: image: webdevops/php-apache-dev:ubuntu-16.04 container_name: web restart: always user: application environment: - WEB_ALIAS_DOMAIN=local.domain.com - WEB_DOCUMENT_ROOT=/app/pub - PHP_DATE_TIMEZONE=EST - PHP_DISPLAY_ERRORS=1 - PHP_MEMORY_LIMIT=2048M - PHP_MAX_EXECUTION_TIME=300 - PHP_POST_MAX_SIZE=500M - PHP_UPLOAD_MAX_FILESIZE=1024M - PHP_DEBUGGER=xdebug - XDEBUG_REMOTE_AUTOSTART=0 - XDEBUG_REMOTE_CONNECT_BACK=0 - XDEBUG_REMOTE_HOST=10.200.10.1 - XDEBUG_REMOTE_PORT=9000 - php.xdebug.remote_enable=1 - php.xdebug.idekey=PHPSTORM volumes: - "/path/to/magento:/app:cached" ports: - "80:80" - "443:443" - "32823:22" links: - mysql mysql: image: mariadb:10 container_name: mysql restart: always ports: - "3306:3306" environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=magento volumes: - db-data:/var/lib/mysql phpmyadmin: container_name: phpmyadmin restart: always image: phpmyadmin/phpmyadmin:latest environment: - MYSQL_ROOT_PASSWORD=root - PMA_USER=root - PMA_PASSWORD=root ports: - "8080:80" links: - mysql:db depends_on: - mysql volumes: db-data: external: false
- After adding your configuration values to the docker-compose.yml file, you'll need to tear it all down and spin it back up.
docker-compose down && docker-compose up -d --build
- These two steps are all it takes to get properly configured and activated.
Create a Network Loopback
What does that even mean? When Xdebug runs, it will try to make a connection to either a specified remote host or connect back to the original IP address that the request came from. Since we are running our VM on our local computer, the original page request comes from localhost or 127.0.0.1. As expected, it attempts to connect back to 127.0.0.1 but fails. This is because 127.0.0.1/localhost, in the eyes of Xdebug, refers back to the server and not your local computer. So basically the request never makes it out of the Docker container.
The solution to this problem is to create a network loopback that will route a specific IP address back to your local machine. The IP address that we've chosen and that you see in the docker-compose.yml file is 10.200.10.1. It will be routed back to your local host machine listening on port 9000.
- Create the network loopback by running this command on your local machine.
sudo ifconfig lo0 alias 10.200.10.1/24
- Optional, but recommended. Store the loopback creation command as an alias on your bash profile so that you can run it simply by typing init-loopback into your terminal. The reason we do this is because when you restart or shut down your computer, the loopback connection goes away. In this case, you'll need to run the command to create the loopback again.
echo 'alias init-loopback="sudo ifconfig lo0 alias 10.200.10.1/24"' >> ~/.bash_profile
- Done! Now you are truly ready to run Xdebug listening on remote host 10.200.10.1 and port 9000.
For demos on how you can use X-debug, watch our YouTube videos. However, you can skip the first video in the playlist. The instructions in this tutorial negate the need for any manual installation.