49

I'm trying to debug a PHP app running on Docker with VSCode, but without success.

In the past I was able to easily debug my PHP apps with VSCode running WAMP Server, but since I started working with Docker I'm unable to get debug working. Searched for several tutorials online, checked some threads here on StackOverflow (ex.: Docker and XDebug not reading breakpoints VSCode), but I'm still not able to get this working.

Dockerfile:

FROM php:7.1.8-apache

COPY /cms /srv/app/cms
COPY .docker/cms/vhosts/vhost.conf /etc/apache2/sites-available/cms.conf
COPY .docker/cms/vhosts/vhost-ssl.conf /etc/apache2/sites-available/cms-ssl.conf
COPY .docker/cms/vhosts/certificate.conf /etc/ssl/certs/certificate.conf
COPY .docker/cms/xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini

WORKDIR /srv/app/cms

RUN docker-php-ext-install mbstring pdo pdo_mysql
RUN pecl install xdebug 
RUN docker-php-ext-enable xdebug
RUN chown -R www-data:www-data /srv/app/cms
RUN openssl req -x509 -new -out /etc/ssl/certs/ssl-cert-cms.crt -config /etc/ssl/certs/certificate.conf
RUN a2ensite cms.conf
RUN a2ensite cms-ssl.conf
RUN a2enmod rewrite
RUN a2enmod ssl

xdebug.ini

[xdebug]
xdebug.default_enable=1
xdebug.remote_enable=1
xdebug.remote_port=9000
xdebug.remote_connect_back=0
xdebug.remote_host='host.docker.internal'
xdebug.idekey='VSCODE'
xdebug.remote_autostart=1

docker-compose.yml

version: '3.7'
services:
cms:
  build:
    context: .
    dockerfile: .docker/cms/Dockerfile
  image: php:7.1.8-apache
  ports:
    - 18080:80
    - 14430:443
  volumes:
    - ./cms:/srv/app/cms
  links:
    - mysql
    - redis
  environment:
    DB_HOST: mysql
    VIRTUAL_HOST: my.app.localhost
    PHP_EXTENSION_XDEBUG: 1

VSCode: launch.json

"configurations": [
    {
        "name": "Listen for XDebug",
        "type": "php",
        "request": "launch",
        "pathMappings": {
           "/srv/app/cms": "${workspaceRoot}/my.app/cms",
        },
        "port": 9000
    }, {
        "name": "Launch currently open script",
        "type": "php",
        "request": "launch",
        "program": "${file}",
        "cwd": "${fileDirname}",
        "port": 9000
    }
]

When I debug the app no breakpoint is being triggered. What am I doing wrong?

UPDATE: Based on some suggestions i've updated my docker-compose.yml and my launch.json files but nothing changed.

docker-compose.yml

ports:
  - 18080:80
  - 14430:443
  - 9000:9000 //added new xdebug default port

launch.json

"configurations": [
    {
        "name": "Listen for XDebug",
        "type": "php",
        "request": "launch",
        "pathMappings": {
           "/srv/app/cms": "${workspaceRoot}/my.app/cms",
        },
        "port": 9000,
        "log": true
    }
]

VSCode Debug Console:

<- launchResponse
Response {
seq: 0,
type: 'response',
request_seq: 2,
command: 'launch',
success: true }

UPDATE #2: Removed the Xdebug port (9000) from the docker-compose.yml settings. Here is the xdebug log result:

Log opened at 2018-09-30 22:21:09 I: Connecting to configured address/port: host.docker.internal:9000. E: Time-out connecting to client (Waited: 200 ms). :-( Log closed at 2018-09-30 22:21:09

Log opened at 2018-09-30 22:21:17 I: Connecting to configured address/port: host.docker.internal:9000. E: Time-out connecting to client (Waited: 200 ms). :-( Log closed at 2018-09-30 22:21:17

Log opened at 2018-09-30 22:21:18 I: Connecting to configured address/port: host.docker.internal:9000. E: Time-out connecting to client (Waited: 200 ms). :-( Log closed at 2018-09-30 22:21:18

Log opened at 2018-09-30 22:21:18 I: Connecting to configured address/port: host.docker.internal:9000. E: Time-out connecting to client (Waited: 200 ms). :-( Log closed at 2018-09-30 22:21:18

Any more suggestions?

7
  • 1) So .. what Xdebug log has to say about it? Show it. 2) What's your host OS? Commented Sep 30, 2018 at 16:31
  • @LazyOne the only output i get in the debug console is this: <- launchResponse Response { seq: 0, type: 'response', request_seq: 2, command: 'launch', success: true } Commented Sep 30, 2018 at 21:20
  • No -- Xdebug's own log, not VSCode. See xdebug.org/docs/all_settings#remote_log Commented Sep 30, 2018 at 21:31
  • 1
    As you can see from the log .. it cannot establish connection with VSCode. It could be: 1) wrong host (but host.docker.internal should be OK). Maybe try platform specific name; 2) Firewall on you host OS (make sure that VSCode can listen on any interface etc); 3) VSCode is not listening (you have not specific your host OS ... so I cannot suggest specific command, but in general -- netstat). Make sure it's VSCode that listens on TCP 9000 port; 4) Docker networking (does not allow connection leave Docker containers/network). Commented Sep 30, 2018 at 22:57
  • 1
    A thousand thanks been trying to get this work since 3 days. Commented Nov 29, 2018 at 20:35

7 Answers 7

30

Managed to solve my issue with the following settings:

launch.json

{
    "version": "0.2.0",
    "configurations": [{
            "name": "Listen for XDebug",
            "type": "php",
            "request": "launch",
            "port": 9000,
            "log": true,
            "externalConsole": false,
            "pathMappings": {
                "/srv/app/cms": "${workspaceRoot}/cms",
            },
            "ignore": [
                "**/vendor/**/*.php"
            ]
        },
    ]
}

xdebug.ini

(copy into container's corresponding dir, i.e.: /usr/local/etc/php/conf.d/xdebug.ini)

zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20160303/xdebug.so
xdebug.default_enable=1
xdebug.remote_enable=1
xdebug.remote_port=9000
xdebug.remote_handler=dbgp
xdebug.remote_connect_back=0
xdebug.remote_host=host.docker.internal
xdebug.idekey=VSCODE
xdebug.remote_autostart=1
xdebug.remote_log=/usr/local/etc/php/xdebug.log
Sign up to request clarification or add additional context in comments.

8 Comments

so in the end you didn't expose port 9000 in docker-compose.yml ?
yes, there's no need to expose the port 9000 in docker.
I was having the same issue for days... I ended up NOT exposing port 9000 from my own docker-compose file and xDebug started working! Thanks a million!
Where do you put the xdebug.ini file? Did you just add that to the end of the php.ini file?
@Jval90 I copy the xdebug.ini file to my docker's container corresponding path: /usr/local/etc/php/conf.d/xdebug.ini
|
8

Since xdebug version 3 there are breaking changes in config names.

My current working dockerfile:

RUN apt-get update; \
        apt-get -y --no-install-recommends install \
            php7.4-dev \
            php-pear \
            libcurl3-openssl-dev \
            libmcrypt-dev \
            libxml2-dev \
            libpng-dev \
        ; \
        pecl install xdebug; \
        { \
            echo "[xdebug]"; \
            echo "zend_extension=$(find /usr/lib/php/ -name xdebug.so)"; \
            echo "xdebug.mode=debug"; \
            echo "xdebug.start_with_request=yes"; \
            echo "xdebug.client_host=host.docker.internal"; \
            echo "xdebug.client_port=9001"; \
        } >> /etc/php/7.4/mods-available/xdebug.ini; \
        phpenmod -v 7.4 xdebug; \

VSC debug config:

    "configurations": [
        {
            "name": "XDebug (Docker)",
            "type": "php",
            "request": "launch",
            "port": 9001,
            "pathMappings": {
                "/var/www/app": "${workspaceRoot}",
            }
        }
    ]

More info: https://xdebug.org/docs/upgrade_guide

Comments

4

Well, I have tried all the above answers and have spend hours but got not success because in all the above answer some concepts were not clear to new x-debug user just like me. I wish that I would have know the following concepts before starting setting up x-debugger, running on a docker container or a remote server, with my VS Code's PHP Debug. I am sure this will help searching for the solution of such issue.

X-Debug Settings

I was not certain that if my machine should be considered as client host or server host, though it was obvious but when you have spent hours on configurations then simple things started to get tricky ones.

xdebug.client_host

According to X-debug Docs:

This address should be the address of the machine where your IDE or debugging client is listening for incoming debugging connections.

I think, with the above piece of text needs no explanation. Hence, setup it up as follows in our x-debug configurations i.e. xdebug.ini:

xdebug.client_host=host.docker.internal

xdebug.remote_host

This was a bit tricky config to me. Actually there is no such configurations for x-debug but I kept thinking about it. :-)

PHP-Debug Settings

hostname

I had been using different configurations except this one (as in this thread no one had mentioned this) :-) and there was no success. I then re-explored the docs of PHP Debug came to know that it must get set to localhost in my case, and gave it a try, and boom! It worked!

"hostname": "localhost"

port

The should be set same as the xdebug.client_port and default value is 9300. Repeatedly mentioned in above answers.

pathMappings

This is an other really important config when trying to setup a docker server with your VS Code PHP Debug. It is an object and must map your local directory structure to the server/container directory i.e. /home/user/proj/html: ${workspaceRoot}. I can't further explain it, it did worked for me and I have mentioned it here. I will welcome if someone explain it.

Here are my final settings:

enter image description here

enter image description here

Hope this will help and save your hours :-)

Comments

2

For everyone running on the following stack:

  • Ubuntu
  • XDebug 3
  • Laravel Sail

docker/8.0/php.ini

[xdebug]
xdebug.discover_client_host=true
xdebug.start_with_request=yes 

.env

SAIL_XDEBUG_MODE=develop,debug
# For linux only:
# you may read up about how to get the ip here: https://laravel.com/docs/8.x/sail#debugging-with-xdebug
SAIL_XDEBUG_CONFIG="client_host=172.22.0.1"

launch.json

{
"version": "0.2.0",
"configurations": [
    {
        "name": "Listen for XDebug via Docker",
        "type": "php",
        "request": "launch",
        "port": 9000,
        "log": true,
        "externalConsole": false,
        "pathMappings": {
            "/var/www/html": "${workspaceRoot}/www",
        },
        "ignore": [
            "**/vendor/**/*.php"
        ]
    },
] }

Comments

1

XDEBUG v3 example for Symfony

enter image description here

docker-compose.yml:

###> XDEBUG 3 ###
# Use your client IP here
# Linux: run "ip a | grep docker0"
# Windows (with WSL2): Run "grep nameserver /etc/resolv.conf  | cut -d ' ' -f2"
# MacOS: host.docker.internal
###< XDEBUG 3 ###
environment:
  XDEBUG_CLIENT_HOST: 172.17.0.1
  XDEBUG_CLIENT_PORT: 9003
  PHP_IDE_CONFIG: serverName=Docker
volumes:
  - ./xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini

xdebug.ini

xdebug.mode=debug,coverage
xdebug.start_with_request=yes
xdebug.client_host=${XDEBUG_CLIENT_HOST}
xdebug.client_port=${XDEBUG_CLIENT_PORT}

xdebug.ini for php:7.2-fpm-alpine3.8

zend_extension=xdebug.so

[xdebug]
xdebug.cli_color = 1
xdebug.mode = debug
xdebug.start_with_request = yes
xdebug.discover_client_host = 0
xdebug.client_host=host.docker.internal
xdebug.ideKey=docker

Example config vscode modify pathMappings

launch.json:

{

    "version": "0.2.0",
    "configurations": [{
        "name": "Listen for XDebug",
        "type": "php",
        "request": "launch",
        "port": 9003,
        "log": true,
        "externalConsole": false,
        "pathMappings": {
            "/appdata/www": "${workspaceRoot}/api",
        },
        "ignore": [
            "**/vendor/**/*.php"
        ]
    },
]
}

Comments

0

you are missing port :9000 (or :9001) in the docker-compose.yml,

which needs to be connectable, for the IDE to connect from the outside.

for VSCode the PHP Debug extension might be required to interact with xdebug.

the default launch.json only uses port: 9000 only once - and has log: true.

{
  "configurations": [{
      "name": "Listen for XDebug",
      "type": "php",
      "request": "launch",
      "port": 9000,
      "log": true
    }, {
      "name": "Launch",
      "request": "launch",
      "type": "php",
      "program": "${file}",
      "cwd": "${workspaceRoot}",
      "externalConsole": false
    }
  ]
}

also see vscode-php-debug and starting the debugger.

6 Comments

"which needs to be connectable, for the IDE to connect from the outside." Interesting theory... What about checking Xdebug docs where it clearly says that it's Xdebug that connects to debug client (VSCode in this case) and NOT other way around? So it's not incoming connection (like it's for HTTP(s)) but outgoing and needs no mappings
@LazyOne in case "listening for remote connections" is required (possibly even "connecting back"), the container would need to expose the port. probably with xdebug.remote_connect_back=1... xdebug needs to run inside the container.
it reads: the port to which xdebug tries to connect on the remote host. (which in this case is a container, similar to a remote host or virtual machine).
Could you please clarify that? It's VSCode that listens on Xdebug port (locally, where it is running) and Xdebug does not listen anything, it does not accept any connections as it only sends them out. xdebug.org/docs/remote#communication
Xdebug (run in Docker container/VM) tries to connect to IDE (so it's outgoing connection). You do not need to expose that port in Docker (because it's for incoming connections). If you expose xdebug port in Docker .. then IDE will not be able to listen for incoming connection ... as port will be occupied by Docker. Firewall inside container or something like that (to enable outgoing connection) -- yes, if you have such thing .. but exposing .. for IDE to connect to Xdebug -- nope. P.S. I'm not touching any VSCode configs here as I'm not using it myself.
|
0

XDebug for PHP in VSCode with minimum configuration and using default settings

  • Check PHP version compatibility with XDEBUG
  • No need to expose any port in docker-compose.yml or Dockerfile
  • Install and enable XDebug in Dockerfile:
  •  # Start of Dockerfile
     # You can use any image that includes PHP
     FROM prestashop/prestashop
    
     # Your customizations in the Dockerfile
     # ...
    
     # Install and enable XDebug
     RUN pecl install xdebug
     RUN docker-php-ext-enable xdebug
    
     # Enable XDebug in PHP configuration
     RUN echo '[XDebug] \n\ 
     zend_extension=xdebug.so \n\
     xdebug.mode=develop,debug \n\
     xdebug.client_host=host.docker.internal' >> /usr/local/etc/php/php.ini
    
  • Map the application root directory to the bounded directory on the host machine. In VSCode:
  • Open ./.vscode/launch.json and find your debug profile, or create one
  • Add pathMappings
  • Example:
  • A PHP app which is in /var/www/html in the docker container
  • Bounded to home/user/Documents/myproject/public
  • When you work with VScode you can replace home/user/Documents/myproject with ${workspaceRoot}
  • So the final mapping would be: ${workspaceRoot}/public
  •  {
         "name": "Listen for Xdebug",
         "type": "php",
         "request": "launch",
         "port": 9003,
         "pathMappings": {
             "/var/www/html": "${workspaceRoot}/public",
         }
     }
    

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.