Debug Docker PHP Project on PHPStorm using Xdebug
Tags: docker, php, devops, tutorial
Published: 2021-12-04 16:22:00

# My First Article

In this article I will share my debugging experience with Xdebug on PHP development environment in Docker, but before going any further, I assume you are familiar with `Docker`, `Docker Compose`, and using `PHPStorm` as your IDE.

## Preparation

This my structure code:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ozk2b4pf62xfo6fs3bhc.png)
 
I put all of configuration for docker inside `docker` folder,  but what conf we need for now is only :

- nginx/nginx.conf
- php/conf.d/php.ini
- docker-compose.yml
- Dockerfile
 
Below is all my configuration:

> nginx/nginx.conf

```
server {
    listen 80;
    server_name web;

    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    error_page 404 /index.php;
    root /var/www/public;
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param SERVER_NAME $server_name;
        fastcgi_param SERVER_NAME $host;
    }
    location / {
        try_files $uri $uri/ /index.php?$query_string;
        gzip_static on;
    }
}

```

> Dockerfile

```
FROM php:8.1.0-fpm

ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/

RUN apt-get update && apt-get install -y \
    git \
    curl \
    zip \
    nano \
    vim \
    unzip

RUN chmod +x /usr/local/bin/install-php-extensions && \
    install-php-extensions gd xdebug pdo-mysql

RUN docker-php-ext-install pdo pdo_mysql

RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN php composer-setup.php --install-dir=. --filename=composer
RUN mv composer /usr/local/bin/

COPY ../ /var/www/

WORKDIR /var/www

EXPOSE 9000
```

> docker-compose.yml

```
version: '3.8'

services:
    app:
        build:
            context: ./
            dockerfile: Dockerfile
        image: myapp/php
        container_name: myapp
        restart: always
        working_dir: /var/www/
        volumes:
            - ../:/var/www
            - ./php/conf.d/php.ini:/usr/local/etc/php/php.ini
            - /tmp/xdebug:/tmp/xdebug
    nginx:
        image: nginx:1.19-alpine
        container_name: mywebserver
        restart: always
        ports:
            - 8000:80
        volumes:
            - ../:/var/www
            - ./nginx:/etc/nginx/conf.d

```

> php/conf.d/php.ini
> You just copy default php.ini and add these line of xdebug conf, and remember your `xdebug.idekey` value

```
[Xdebug]

xdebug.mode=debug,trace
xdebug.client_host=docker.for.mac.host.internal
xdebug.client_port=9003
xdebug.idekey = docker

```
> note : `host.docker.internal` for linux

## Let's debugging

I hope your container runs without any problems, then now we are going to configure PHPStorm.

1. Here we want to configure our PHP docker interpreter.
  a. Go to `Preferences > PHP, add new interpreter, select new interpreter from Docker, vagrant, etc...

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hy5swoo29y6hxcbo597w.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n2aildq0pllhnp6if7s9.png) 
  b. Create new Server.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m0vgsspiw2betr2k7dc4.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k8ybpphk0z1ja593bu4e.png)
 
  c. After selecting an Interpreter, we are going to map our working project with container path, my working project path is `$HOME/DOO/api docker` and I will map into `/var/www/`, so change the `Docker container` value:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ss79mxlcgue9kk14haln.png)
  
  d. This the result :
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/73fkt9bkkj1ol7m43gu6.png)

2. Xdebug configuration.
  a. Go to `Preferences > PHP > Debug`, set like this:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rgw7h1myum1a234pk2xr.png)
  b. Go to `Preferences > PHP > Debug > Dbgp Proxy`, set like this (note: IDE Key must same with the value of `xdebug.idekey` on `php.ini`):  
 ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wifwfsec6uaum4sosiiw.png)
  c. Go to `Run > Edit Configurations...`, create a new `PHP Remote Debug` configuration:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/et2pfh3vdt6s1uc179zs.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8ph5obtmuc0q6m4terad.png)
  d. Go to `Run > Web Server Debug Validation`, on `Path to create validation script` I point the value into my `public` path of project, and `URL to validation script` I point to my nginx docker host.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hmftgwuirx26mctnqve0.png)

3. EXECUTE!
  a. Set breakpoint, and turning on `Start Listening for PHP Debug Connection` 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mkcvkv77nlvlpu0fhjdz.png) 
 
 ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1dirxryrysns6p47hduz.png)
 
  b. Go to `Run > Debug` then select the configuration what we made earlier (PHP Remote Debug):
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y2u64ax01bt7eoioly72.png)

  c. Go to your endpoint, and add query string with parameter `XDEBUG_SESSION_START` and the value is your `IDE Key`, then execute! :
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vghuigr95oz3ax0q8hm5.png)
 
Taraaaaa! 
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bhc5dkcq6ppqysfpgn2k.png)