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.
Well, I share my Docker assets. Here you are. This is php.ini file.
[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.
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.
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.
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 this document. I started my web application by using this command.
docker-compose up --build
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.
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.
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.
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.
Top comments (11)
I see that you put xdebug config direct in dockerfile it's bad approach. You can create a file
called xdebug.ini it can look like the following:
[Xdebug]
xdebug.remote_autostart=0
xdebug.remote_enable=1
xdebug.default_enable=0
xdebug.remote_host=host.docker.internal
xdebug.remote_port=9000
xdebug.remote_connect_back=0
xdebug.profiler_enable=0
xdebug.remote_log="/tmp/xdebug.log"
xdebug.profiler_output_dir="/var/www/html/profiler"
xdebug.profiler_output_name="cachegrind.out.%p"
xdebug.cli_color=1
xdebug.profiler_append=1
after that copy that one into /usr/local/etc/php/conf.d/
This is a lot cleaner, also since we use prebuilt docker images we cant just change the dockerfile. I've not been able to get it to work the way you explained, but i'll try again later ;)
Thank you for reply, it's prettier solution as you said.
I've used this
xdebug.ini
placed in/usr/local/etc/php/conf.d/
Where
host.docker.internal
is the proper way to access your host ip address in a containerized app in Docker Desktop clients.Also you need to add the next line to your Dockerfile or set
environment
field indocker-compose.yml
After that you need to press "Start listen on PHP debug connections" (phone icon), set a breakpoint and start a debug session (bug icon). To trigger the debug session you access your API endpoint via GET, POST, with query param
?XDEBUG_SESSION_START=PHPSTORM
or cookie set toXDEBUG_SESSION = PHPSTORM
. To set this cookie easily you can use Xdebug Helper extension or a similar one.Thank you so much for this guide! I was struggling all day to make my Wordpress in Docker on Windows setup work with xdebug. This post had all the missing details like how to have xdebug connect to PhpStorm running on the host.
I'm glad to hear that, happy coding :)
Why you use the big php.ini like this. Something looks unnecessary.
yep, I just wanted the audience to know we can do.
Hello Dear! In my case ,following your last point, browser keeps loading. But debbuger variables area is not being populated. Can you please help
Hi! Is there any error? How can I help you with it?
There is no error. But variables are not also being shown in debugger area.
I am not using Symphony, but a simply all code is in index.php file within app/public folder as specified by you. Can there be any mapping issue in this case? My mappings are same as specified by you