Using Xdebug with Docker
Tags: docker, php, testing, beginners
Published: 2019-04-07 22:08:27

---
title: Using Xdebug with Docker
published: true
description: We will able to use Xdebug by Docker
tags: #docker #php #testing #beginners
---

I am going to show using Xdebug with Docker. Because, as long as you prefer using Xdebug on development workspace with Docker, you have to create remote connection of the Xdebug. First of all, you must have a Xdebug client. I would rather use PhpStorm for this. With this way, I am going to mention some hints and ways to use smoothly. Let's start!

I would like to start a Symfony project which is running on Docker. I will tell this independent from Symfony. Through Docker Compose helps me about it. My structure is like as the following.

![alt text](https://thepracticaldev.s3.amazonaws.com/i/bvt2h351i7m1zf2acuyl.png "")

Well, I share my Docker assets. Here you are. This is **php.ini** file.

```php
[PHP]
engine = On
short_open_tag = On
precision = 14
output_buffering = Off
zlib.output_compression = Off
implicit_flush = Off
unserialize_callback_func =
serialize_precision = 100
disable_functions = dl
disable_classes =
zend.enable_gc = On
expose_php = Off
max_execution_time = 30
max_input_time = 60
memory_limit = 256M
error_reporting = E_ALL & ~E_NOTICE
display_errors = On
display_startup_errors = Off
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
track_errors = Off
html_errors = On
error_log = error_l
variables_order = "EGPCS"
request_order = "GP"
register_argc_argv = On
auto_globals_jit = On
post_max_size = 64M
auto_prepend_file =
auto_append_file =
default_mimetype = "text/html"
default_charset = "UTF-8"
include_path = ".:/opt/php72/lib/php"
doc_root =
user_dir =
enable_dl = Off
file_uploads = On
upload_max_filesize = 64M
max_file_uploads = 20
allow_url_fopen = On
allow_url_include = On
default_socket_timeout 
cli_server.color 
date.timezone = Asia/Riyadh
pdo_mysql.cache_size = 2000
pdo_mysql.default_soc
sendmail_path = /usr/sbin/sendmail -t 
mail.add_x_header 
sql.safe_mode =
odbc.allow_persistent = Off
odbc.check_persistent = Off
odbc.max_persistent = -1
odbc.max_links = -1
odbc.defaultlrl = 4096
odbc.defaultbinmode
ibase.allow_persistent = 1
ibase.max_persistent = -1
ibase.max_links = -1
ibase.timestampformat = "%Y-%m-%d %H:%M:%S"
ibase.dateformat = "%Y-%m-%d"
ibase.timeformat = "%H:%M"
mysqli.max_persistent = -1
mysqli.allow_persistent = Off
mysqli.max_links = -1
mysqli.cache_size = 2000
mysqli.default_port = 3306
mysqli.default_socket =
mysqli.default_host =
mysqli.default_user =
mysqli.default_pw =
mysqli.reconnect =
mysqlnd.collect_statistics = Off
mysqlnd.collect_memory_statistics =
pgsql.allow_persistent = Off
pgsql.auto_reset_persistent = Off
pgsql.max_persistent = -1
pgsql.max_links = -1
pgsql.ignore_notice = 0
pgsql.log_notice
bcmath.scale
session.save_handler = files
session.save_path = "/tmp"
session.use_strict_mode = 0
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 100
session.gc_maxlifetime = 1440
session.referer_check =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.hash_function = 0
session.hash_bits_per_character = 5
url_rewriter.tags = "a=href,area=href,frame=src,input=src,form=,fields"
zend.assertions 
tidy.clean_output =
soap.wsdl_cache_enabled=1
soap.wsdl_cache_dir="/tmp"
soap.wsdl_cache_ttl=86400
soap.wsdl_cache_limit
ldap.max_links
```

Second one is **nginx.conf**.

```bash
server {
    listen 80;
    server_name web;
    root /var/www/app/public;

    location / {
        # try to serve file directly, fallback to index.php
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/index\.php(/|$) {
        #fastcgi_pass unix:/var/run/php7.2-fpm.sock;
        fastcgi_pass php:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;
        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
        fastcgi_busy_buffers_size 256k;
        internal;
    }

    location ~ \.php$ {
        return 404;
    }

    error_log /var/log/nginx/project_error.log;
    access_log /var/log/nginx/project_access.log;
}
```

And third one is the **Dockerfile**. The important points are on here. 

```bash
FROM php:7.2-fpm-alpine

RUN apk update \
    && apk add  --no-cache git mysql-client curl libmcrypt libmcrypt-dev openssh-client icu-dev \
    libxml2-dev freetype-dev libpng-dev libjpeg-turbo-dev g++ make autoconf \
    && docker-php-source extract \
    && pecl install xdebug redis \
    && docker-php-ext-enable xdebug redis \
    && docker-php-source delete \
    && docker-php-ext-install pdo_mysql soap intl zip \
    && echo "xdebug.remote_enable=on" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
    && echo "xdebug.remote_autostart=off" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
    && echo "xdebug.remote_port=9001" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
    && echo "xdebug.remote_handler=dbgp" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
    && echo "xdebug.remote_connect_back=0" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
    && echo "xdebug.idekey=mertblog.net" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
    && echo "xdebug.remote_host=docker.for.mac.localhost" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
    && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
    && rm -rf /tmp/*

CMD ["php-fpm", "-F"]

WORKDIR /var/www/app

EXPOSE 9000
```

If you haven't got Mac OS, you're supposed to change **xdebug.remote_host** as your machine IP. In addition to this, as you see, my idekey is **mertblog.net** and my remote_port is **9001**. You are able to change it. Finally, let me show **docker-compose.yml** file.

```yaml
version: '3'
services:
    php:
        build:
            context: ./php-fpm/.
        volumes:
            - ./app:/var/www/app
            - ./php-fpm/php.ini:/usr/local/etc/php/php.ini
        depends_on:
            - mysql
    web:
        image: nginx:latest
        ports:
            - "8888:80"
        volumes:
            - ./app:/var/www/app
            - ./nginx/app.conf:/etc/nginx/conf.d/default.conf
        depends_on:
            - php
    mysql:
        image: mysql:5.7
        environment:
            MYSQL_ROOT_PASSWORD: symf0ny
        ports:
            - "3333:3306"
```


I installed the Symfony application which I've refered <a href="https://symfony.com/doc/current/setup.html" target="_blank">this document.</a> I started my web application by using this command. 

```bash
docker-compose up --build
```

![alt text](https://thepracticaldev.s3.amazonaws.com/i/wn9uw7o12s4aae8rku2t.png "")

From now on, I could configure the Xdebug client. For this, follow this path from the interface. **Phpstorm > Preferences > PHP > Debug**. You are going to see **Xdebug Debug Port**. You should change as **9001** port. After that, follow this path **Phpstorm > Preferences > PHP > Servers**. You are going to see this screen.

![alt text](https://thepracticaldev.s3.amazonaws.com/i/oxbpqozlwm7ku8pir69b.png "")

I've set the name **docker-server**. My host is localhost and my web server post is **8888**. Click the `Use path mappings`. You have to define the `Absolute path on the server` as **/var/www/app**. It links to our project directory on the local machine. Well, after this, you close this screen and click the `Edit Configurations` section on the left side. 

![alt text](https://thepracticaldev.s3.amazonaws.com/i/aexdyrsabyqrq108ec32.png "")

![alt text](https://thepracticaldev.s3.amazonaws.com/i/hkq9udylhswkltn5xzgv.png "")

On this section, we are going to create a configuration under to **PHP Remote Debug**. I've set the name as `docker`. My server is `docker-server` which I've created just before. And Ide Key is same thing in the `Dockerfile`.

I clicked the phone icon to start listening **PHP Debug Connections**.

![alt text](https://thepracticaldev.s3.amazonaws.com/i/y503q2otcrjy1dvkofx8.png "")

Right, I can start my Xdebug session by getting this url. http://localhost:8888/home?XDEBUG_SESSION_START=mertblog.net

I've put red point on the 19th line. From now on, I am able to debug my variables on PHPStorm interface obviously. It truly helps us and with this way we could notice mistakes easily. 

![alt text](https://thepracticaldev.s3.amazonaws.com/i/ichtz0s3lxua9yhlxo2g.png "")