Ricky
Ricky

Reputation: 3072

Debug PHP with VSCode and Docker

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?

Upvotes: 48

Views: 42788

Answers (7)

Ricky
Ricky

Reputation: 3072

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

Upvotes: 29

Ali Samie
Ali Samie

Reputation: 470

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",
         }
     }
    

Upvotes: 0

maccevedor
maccevedor

Reputation: 165

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"
        ]
    },
]
}

Upvotes: 1

Khuram
Khuram

Reputation: 1850

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 :-)

Upvotes: 4

Sylver11
Sylver11

Reputation: 199

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"
        ]
    },
] }

Upvotes: 2

Mateusz Przybylek
Mateusz Przybylek

Reputation: 5855

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

Upvotes: 8

Martin Zeitler
Martin Zeitler

Reputation: 76699

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.

Upvotes: 0

Related Questions