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
Answer from progonkpa on Stack OverflowXdebug 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
Add the remote_connect_back=on, so xdebug connects to the current visitor (using the REMOTE_ADDR system variable) instead of the remote_host which may change. You can try with remote_autostart=on too, to make sure this issue is not related with the browser itself.
Remember to configure the mapping in phpStorm as well, but it will tell you to do so anyway. Also make sure the IDE is listening to the debug session (small toggle in the debug toolbar). Good luck.
Videos
RUN apk add --no-cache $PHPIZE_DEPS \
&& pecl install xdebug-2.9.2 \
&& docker-php-ext-enable xdebug \
I found this instructions here on how to set it up. Add it to the end of the php.dockerfile:
# Install base packages
RUN apk update
RUN apk upgrade
# xdebug with VSCODE
ENV XDEBUG_VERSION=2.9.2
RUN apk --no-cache add --virtual .build-deps \
g++ \
autoconf \
make && \
pecl install xdebug-${XDEBUG_VERSION} && \
docker-php-ext-enable xdebug && \
apk del .build-deps && \
rm -r /tmp/pear/* && \
echo -e "xdebug.remote_enable=1\n\
xdebug.remote_autostart=1\n\
xdebug.remote_connect_back=0\n\
xdebug.remote_port=9001\n\
xdebug.idekey=\"VSCODE\"\n\
xdebug.remote_log=/var/www/html/xdebug.log\n\
xdebug.remote_host=host.docker.internal" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
# Change TimeZone
RUN apk add --update tzdata
ENV TZ=Europe/Bucharest
EDIT: You should also remove the xdebug port in docker-compose.yml (In case you added it)
For **Visual Studio Code** Here is the kaunch.json I used:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Listen for XDebug",
"type": "php",
"request": "launch",
"port": 9001,
"pathMappings": {
"/var/www/html/public": "${workspaceFolder}/src/public"
},
}
]
}
But at Start listening for PHP Debug connection I get
Port 9009 is busy
There is no need to expose Xdebug port in your Docker container, no need at all.
If you expose it .. Docker will be the one that listens on that port and forwards any connections into container. But it's IDE/VSCode/PhpStorm that must be listening it... because it's Xdebug that connects to IDE and NOT other way around.
Fix that first.
xdebug.remote_connect_back = 1
I recommend turning this off and specify actual host in xdebug.remote_host (docker.for.mac.localhost).
The IP detected by Xdebug with remote_connect_back option (depends on settings I guess, and the way how Docker works) very likely will not be the IP of the host machine. But that's what you need -- that's where your IDE (PhpStorm) / editor (VSCode) runs and Xdebug must be connecting to.
If you are on "Docker for Mac", then in you xdebug config file you can also use this:
xdebug.remote_host = host.docker.internal
I WANT TO CONNECT FROM A CONTAINER TO A SERVICE ON THE HOST
The host has a changing IP address (or none if you have no network access). From 18.03 onwards our recommendation is to connect to the special DNS name host.docker.internal, which resolves to the internal IP address used by the host. This is for development purpose and will not work in a production environment outside of Docker for Mac.
The gateway is also reachable as gateway.docker.internal.
The following is sufficient for simply installing xdebug on that image:
FROM wordpress:php7.1-fpm-alpine
RUN apk add --no-cache $PHPIZE_DEPS \
&& pecl install xdebug-2.5.0 \
&& docker-php-ext-enable xdebug
Building that and then running from a shell inside the resulting image produces the following:
$ php -i | grep Xdebug
with Xdebug v2.5.0, Copyright (c) 2002-2016, by Derick Rethans
If you are concerned about image size you can remove the dependencies:
FROM wordpress:php7.1-fpm-alpine
RUN apk --update --no-cache add autoconf g++ make && \
pecl install -f xdebug && \
docker-php-ext-enable xdebug && \
apk del --purge autoconf g++ make