Debugging Web Applications In PHPStorm With Xdebug And Docker
Overview
How to debug a PHP web application in PHPStorm using Docker and XDebug. [1] [2]
PHP configuration
Make sure that a PHP interpreter is selected, and that the PHP installation has XDebug included.
In PHPStorm: Preferences > Language & Frameworks > PHP > CLI interpreter
From the command line: php -v. Make sure that the xdebug extension is displayed.
Docker server
The Docker server is a virtual Linux server that runs the web server which is used to host the web application to be debugged. It is important to keep in mind that the software and filesystem of this server is independent of the local filesystem where the app is being developed.
When this virtual server is spun up, it must be configured such that it can host the web application in a state where it can be run and debugged.
Preferences > PHP > Servers
Click the "plus" icon to create a new server.
- Name:
docker-server - Host: localhost
- Port: 80
- Debugger: Xdebug
- Use path mappings:
checked
Then under path mappings create associations between project files and their respective locations in the Docker container, e.g.:
/project_root/app/>/var/www/html//project_root/keys/>/var/www/keys//project_root/vendor/>/var/www/html/vendor/
The host and port reference host and port within the Docker container. This applies to the path mappings as well.
The container's HTML root is /var/www/html. This path may or may not exist on the local file system, but that doesn't impact anything here.
Two project file directories cannot point to the same path on the server (e.g. bfhhand_web and common_lib can't coexist in the same root directory as they do on production.)
Run configuration
Run > Edit Configurations...
Click the "plus" icon to create a new Debug Configuration.
Select PHP Remote Debug
- Name: docker
- Server: docker-server
- IDE key: docker
docker-server is the server that was created in the previous step.
The value of the IDE Key must match the value that is put into the xdebug.ini file that is created later in the process.
Xdebug preferences
These are the defaults, they can be confirmed, but don't need to be changed
Preferences > Languages & Frameworks > PHP > Debug > Xdebug
- Debug port: 9003
- Can accept external connections:
checked
9003 is the default port for XDebug v3. 9000 is the default port for XDebug v2.
Docker container configuration
The three files used in the Docker container configuration (Dockerfile, xdebug.ini, docker-compose.yml) are all located in the PHPStorm project root directory. These files should not be uploaded to production. The actual web files should be placed one directory down from the root, e.g. in a directory named app.
Dockerfile
FROM php:7.4-apache
# install utilities such as curl, git, vim
RUN apt-get update && \
apt-get install --no-install-recommends --assume-yes --quiet \
ca-certificates \
curl \
git \
vim \
libonig-dev && \
rm -rf /var/lib/apt/lists/*
# install php extensions redis, xdebug, mysqli, etc.
RUN pecl install redis-5.3.4 && \
pecl install xdebug && \
docker-php-ext-install mbstring pdo pdo_mysql mysqli && \
docker-php-ext-enable redis xdebug
# create accessible apache logs
RUN mkdir /var/log/httpd/
ENV APACHE_LOG_DIR /var/log/httpd
# enable mod_rewrite
RUN a2enmod headers rewrite
# enable 'AuthGroupFile' in .htaccess
RUN a2enmod authz_groupfile
# remove .htaccess to allow debugger to connect
# RUN rm /var/www/html/.htaccess
# bypass CMS password in development environment
RUN mkdir /home/myacct/ && \
mkdir /home/myacct/.htpasswds/ && \
mkdir /home/myacct/.htpasswds/mysite/
COPY app/.htaccess /home/myacct/.htpasswds/mysite/
RUN mkdir /home/chicot/ && \
mkdir /home/chicot/keys/ && \
mkdir /home/chicot/keys/littledamien
COPY keys/littledamien/passwd /home/chicot/keys/littledamien/
# Xdebug settings
RUN cp /usr/local/etc/php/php.ini-production /usr/local/etc/php/php.ini && \
echo "xdebug.mode=debug" >> /usr/local/etc/php/php.ini && \
echo "xdebug.start_with_request=yes" >> /usr/local/etc/php/php.ini && \
echo "xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/php.ini
# make httpd accessible
EXPOSE "80"
The most important functions of this file are
- Pull a PHP image.
- Install Xdebug and MySql PHP extensions.
- Copies the production php.ini included in the PHP distribution as the working php.ini file.
- Configures XDebug within PHP to allow for remote debugging.
xdebug.mode=debugenables XDebugxdebug.start_with_request=yesallows for debugging without a browser extension to start debugging sessions.xdebug.client_host=host.docker.internalgives permission to the client IDE to connect to XDebug on the Docker server.
- Makes http port 80 available in the container.
Other conveniences built into the file:
- Install curl, git, and vim in the container.
- Log server errors to accessible log file.
- Enable
mod_rewritedirectives and any non-default modules referenced in.htaccess.
See XDebug Dockerfile With PHP 5.x for a previous version of the Dockerfile.
xdebug.ini
xdebug.ini file onto the Docker server to configure XDebug within PHP. This has been replaced with specifying xdebug settings in the php.ini file on the server. This is accomplished in Dockerfile. See xdebug.ini Configuration For XDebug Version 3 for archived XDebug settings.docker-compose.yml
version: '2'
services:
app:
build:
context: .
image: xdebug-bfhhand:latest
volumes:
- ./:/var/www/html
- ~/develop/bfhhand/keys:/var/www/keys
- ~/develop/common_lib:/var/www/html/common_lib
ports:
- "80:80"
- The
contextdirective specifies where theDockerfileis located. imagespecifies the name of the Docker container that will be created.volumesmaps local directories to directories in the Docker container. These mappings correspond to the mappings found in PHPStorm > Preferences > Language & Frameworks > PHP > Servers >docker> path mappings.portsmaps the port used to reach the container with the port used inside the container.
Managing the Docker server
Start the Docker server
$ docker-compose build $ docker-compose up -d $ curl localhost
or simply
$ docker-compose up -d --build $ curl localhost
The -d option is for "detached" to get the terminal prompt back after running the command.
The server is tested with curl localhost.
Stop the Docker server
$ docker-compose down
Remove the image with
$ docker rmi [IMAGE_NAME]
Validating th server in PHPStorm
Run menu > Web Server Debug Validation
- Local Web Server Or Shared Folder
- URL to validation script:
http://localhost
Connecting the the Docker container with PHPStorm
Chrome extension
xdebug.start_with_request=1.Install XDebug Helper extension in browser.
In the extension options, select PHPStorm as the predefined IDE key (PHPSTORM) or "Other" to specify a custom IDE key. This key must match the key specified in the docker run configuration (Run menu > Edit Configurations... > IDE Key (Session ID)), and it must match the xdebug.idekey value in xdebug.ini.
Make sure that the extension is active by clicking on the extension icon in the browser toolbar, and selecting "Debug". The icon is gray when disabled and green when enabled.
PHPStorm
After creating the "docker" run configuration in PHPStorm (see above), "docker" will be one of the options available in the run configuration drop-down in the top toolbar.
Select docker in that dropdown to make it the active run configuration, however it's not necessary to start a debugging session.
Select Run > Start Listening for PHP Debug Connections to have PHPStorm listen for connections to the docker server, i.e. requests for "localhost" in a browser.
Request site content
Then in a browser make a request for http://localhost, or in a terminal window enter curl localhost. The IDE will automatically catch the request and break at any breakpoints.
Select Run > Break at first line in PHP scripts to catch all requests to the docker server, or place a breakpoint in the page of interest.
Uploading edits
Any changes to the source files in PHPStorm are immediately available on the server. The volumes directive in docker-compose.yml creates the links between the local source directories and the server directories.
Database connections
Assuming the development database server is running on the same machine as PHPStorm. "localhost" to the Docker web server is the Docker container, and not the development machine. Use host.docker.internal as the host setting for database connections. This will resolve as the development machine for the web server.
See also
External links
- Zero-Configuration Debugging -- PHPStorm Documentation
- Docker Cookbook
- Xdebug Extension for PHP documentation
Notes
- ↑ Getting xDebug to Work - Servers For Hackers
- ↑ Debug your PHP in Docker with Intellij/PHPStorm and Xdebug - GitHub Gist
