Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Configure Xdebug in PHP-FPM Docker container

I'm basically using this configuration to create the development environment for a Symfony project https://github.com/maxpou/docker-symfony. It runs but I can't get Xdebug to work: it doesn't stop when I set a breakpoint.

I also tried to configure Xdebug to use connect_back but that doesn't work. Maybe it's related to the fact that I'm developing on a Windows machine? Any insights are much appreciated.

Dockerfile PHP:FPM

# See https://github.com/docker-library/php/blob/master/7.1/fpm/Dockerfile
FROM php:7.1-fpm
ARG TIMEZONE

MAINTAINER Maxence POUTORD <[email protected]>

RUN apt-get update && apt-get install -y \
    openssl \
    git \
    unzip

# Install Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN composer --version

# Set timezone
RUN ln -snf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime && echo ${TIMEZONE} > /etc/timezone
RUN printf '[PHP]\ndate.timezone = "%s"\n', ${TIMEZONE} > /usr/local/etc/php/conf.d/tzone.ini
RUN "date"

# Type docker-php-ext-install to see available extensions
RUN docker-php-ext-install pdo pdo_mysql


# install xdebug
RUN pecl install xdebug
RUN docker-php-ext-enable xdebug
RUN echo "error_reporting = E_ALL" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo "display_startup_errors = On" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo "display_errors = On" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo "xdebug.remote_enable=1" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
#RUN echo "xdebug.remote_connect_back=1" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo "xdebug.idekey=\"PHPSTORM\"" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo "xdebug.remote_port=9000" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo "xdebug.remote_autostart=1" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
# DockerNAT gateway IP
RUN echo "xdebug.remote.host=10.0.75.1" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo "xdebug.remote.mode=req" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo "xdebug.remote.handler=dbgp" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini


RUN echo 'alias sf="php app/console"' >> ~/.bashrc
RUN echo 'alias sf3="php bin/console"' >> ~/.bashrc

WORKDIR /var/www/free-energy/symfony

docker-compose.yml:

# https://github.com/maxpou/docker-symfony
version: '2'

services:
    db:
        image: mysql
        volumes:
            - "./.data/db:/var/lib/mysql"
        environment:
            MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
            MYSQL_DATABASE: ${MYSQL_DATABASE}
            MYSQL_USER: ${MYSQL_USER}
            MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    php:
        build:
            context: php7-fpm
            args:
                TIMEZONE: ${TIMEZONE}
        volumes:
            - ${SYMFONY_APP_PATH}:/var/www/free-energy/symfony
            - ./logs/symfony:/var/www/free-energy/symfony/app/logs
        environment:
            PHP_IDE_CONFIG: serverName=free-energy.org
    nginx:
        build: nginx
        ports:
            - 80:80
        volumes_from:
            - php
        volumes:
            - ./logs/nginx/:/var/log/nginx
    elk:
        image: willdurand/elk
        ports:
            - 81:80
        volumes:
            - ./elk/logstash:/etc/logstash
            - ./elk/logstash/patterns:/opt/logstash/patterns
        volumes_from:
            - php
            - nginx
like image 872
progonkpa Avatar asked Dec 29 '17 18:12

progonkpa


People also ask

Where is xdebug config?

For Windows[edit] ini" file to configure XDebug. The "Loaded Configuration File" in the screenshot above tells you what "php. ini" file is being used. For Windows, this is normally "c:\xampp\apache\bin\php.

How does PHP xdebug work?

When Xdebug is running, it will call back to your IDE (like PhpStorm or VS Code) from the server where it's running. Your IDE will sit and listen for that connection on a specific port (typically port 9000 or 9003).


Video Answer


1 Answers

Xdebug traffic wasn't finding it's way back to my host. When I entered the IP-address of my host machine in xdebug.remote_host, debugging worked but this was not ideal because my IP changes on every reboot. Luckily, Docker provides a way to obtain the host IP via a DNS-entry docker.for.win.localhost.

Edit:
Docker now has a platform-independent DNS-entry host.docker.internal.

I tried to use xdebug.remote_connect_back=1 which just responds to traffic from where it came but it wasn't working. Phpinfo() showed that REMOTE_ADDR was set to localhost. Localhost in this context points to the Docker PHP-container while it should point to our host IP. Important to know with this setting is that xdebug.remote_host in the .ini will be ignored.

From the Xdebug docs:

xdebug.remote_connect_back Type: boolean, Default value: 0, Introduced in Xdebug >= 2.1

If enabled, the xdebug.remote_host setting is ignored and Xdebug will try to connect to the client that made the HTTP request.

Here is the Dockerfile with the xdebug.ini configuration for the PHP Docker container that worked:

FROM php:7.1-fpm
ARG TIMEZONE

MAINTAINER Maxence POUTORD <[email protected]>

RUN apt-get update && apt-get install -y \
    openssl \
    git \
    unzip

# Install Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN composer --version

# Set timezone
RUN ln -snf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime && echo ${TIMEZONE} > /etc/timezone
RUN printf '[PHP]\ndate.timezone = "%s"\n', ${TIMEZONE} > /usr/local/etc/php/conf.d/tzone.ini
RUN "date"

# Type docker-php-ext-install to see available extensions
RUN docker-php-ext-install pdo pdo_mysql

# install xdebug
RUN pecl install xdebug
RUN docker-php-ext-enable xdebug
RUN echo "zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20160303/xdebug.so" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo "error_reporting = E_ALL" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo "display_startup_errors = On" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo "display_errors = On" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini

# relevant to this answer
RUN echo "xdebug.idekey=\"PHPSTORM\"" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo "xdebug.remote_port=9000" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo "xdebug.remote_enable=1" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo "xdebug.remote_autostart=1" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN echo "xdebug.remote_host=docker.for.win.localhost" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini

RUN echo 'alias sf="php app/console"' >> ~/.bashrc
RUN echo 'alias sf3="php bin/console"' >> ~/.bashrc

WORKDIR /var/www/free-energy/symfony


Edit:
I was messing around with XDebug quite a bit in this post.
Now I know your XDebug config doesn't have to be as big as I had back then.

xdebug.ini: (in your Docker PHP image).

zend_extension=xdebug.so

[Xdebug]
xdebug.remote_enable=true
xdebug.remote_port=9000
xdebug.remote_host=host.docker.internal
like image 159
progonkpa Avatar answered Sep 25 '22 00:09

progonkpa