0

I've enabled xdebug in a docker container but see the following in the log:

server-1   | [18] Log opened at 2025-03-07 12:42:03.355682
server-1   | [18] [Config] INFO: Control socket set up successfully: '@xdebug-ctrl.18'
server-1   | [18] [Step Debug] INFO: Connecting to configured address/port: host.docker.internal:9003.
server-1   | [18] [Step Debug] WARN: Creating socket for 'host.docker.internal:9003', poll success, but error: Operation now in progress (29).
server-1   | [18] [Step Debug] WARN: Creating socket for 'host.docker.internal:9003', connect: Network is unreachable.
server-1   | [18] [Step Debug] ERR: Could not connect to debugging client. Tried: host.docker.internal:9003 (through xdebug.client_host/xdebug.client_port).  
server-1   | [18] Log closed at 2025-03-07 12:42:03.366018

It seems that xdebug is not able to connect outside the server-1 container. The compose.yaml and Dockerfile where created with docker init and only slightly adjusted:

compose.yaml:

services:
  server:
    build:
      context: .
    ports:
      - 9000:80
    volumes:
      - ./htdocs:/var/www/html

  db:
    image: mariadb
    restart: always
    environment:
      MARIADB_ROOT_PASSWORD: geheim

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080

Dockerfile:

################################################################################

# Create a stage for installing app dependencies defined in Composer.
FROM composer:lts as deps

WORKDIR /app

RUN --mount=type=bind,source=composer.json,target=composer.json \
    --mount=type=bind,source=composer.lock,target=composer.lock \
    --mount=type=cache,target=/tmp/cache \
    composer install --no-dev --no-interaction

FROM php:8.3.12-apache as final

RUN a2enmod rewrite
RUN pecl install xdebug-3.4.1 && docker-php-ext-enable xdebug
RUN apt-get update && apt-get install -y libmariadb-dev \
    && docker-php-ext-install mysqli pdo_mysql \
    && docker-php-ext-enable mysqli pdo_mysql


# Use the default production configuration for PHP runtime arguments, see
# https://github.com/docker-library/docs/tree/master/php#configuration
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
RUN echo "xdebug=true" >> "$PHP_INI_DIR/php.ini"
RUN echo "xdebug.mode=debug" >> "$PHP_INI_DIR/php.ini"
# RUN echo "xdebug.discover_client_host=false" >> "$PHP_INI_DIR/php.ini"
RUN echo "xdebug.client_host=host.docker.internal" >> "$PHP_INI_DIR/php.ini"
RUN echo "xdebug.start_with_request=yes" >> "$PHP_INI_DIR/php.ini"
RUN echo "xdebug.log=/dev/stdout" >> "$PHP_INI_DIR/php.ini"

COPY --from=deps app/vendor/ /var/www/html/vendor


USER www-data

VSCode is listening with this:

launch.json

{
    // 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",
            "hostname": "host.docker.internal",
            "port": 9003
        },
}

Adding this to compose.yaml

    extra_hosts:
      - "host.docker.internal:host-gateway"

has no effect.

EDIT: After updating launch.json and removing the line "hostname": "host.docker.internal", XDebug was able to connect to the VSCode debug session. However a new problem appeared in the xdebug.log:

...
server-1   | [19] [Step Debug] <- breakpoint_set -i 6 -t line -f file:///d:/Projekte/Bildung/Leaderboard/htdocs/info.php -n 2
server-1   | [19] [Step Debug] WARN: Breakpoint file name does not exist: d:/Projekte/Bildung/Leaderboard/htdocs/info.php (No such file or directory).        
server-1   | [19] [Step Debug] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="breakpoint_set" transaction_id="6" id="190001" resolved="unresolved"></response>
...

The file does exist, however.

7
  • Add this extra_hosts: - "host.docker.internal:host-gateway" in your compose.yaml Commented Mar 7 at 13:17
  • check your Xdebug configuration : xdebug.mode=debug xdebug.start_with_request=yes xdebug.client_host=host.docker.internal xdebug.client_port=9003 xdebug.log=/dev/stdout Check the php.ini too Commented Mar 7 at 13:19
  • @RanadipDutta you see the xdebug setup in the Dockerfile. Port 9003 is default and has not to be specified. The php ini is interpreted correctly according to phpinfo(); Commented Mar 7 at 13:45
  • I will post as an answer. There are multiple things to check even in php.ini as well. Commented Mar 7 at 13:50
  • @RanadipDutta the php.ini is not in error. I will add an edit Commented Mar 7 at 13:52

1 Answer 1

0

After I added pathMappings section to the launch.json I had it working. For completness here my solution:

Project folder

leaderboard
├───htdocs
│   ├───api
│   ├───classes
│   ├───config
│   ├───discovered
│   │   └───Sbw
│   │       └───Leaderboard
│   ├───inc
│   └───vendor
└───logs

Docker setup files (Dockerfile and compose.yaml) sit in the top "leaderboard" folder; the app in the htdocs subfolder.

Docker layout

Dockerfile

# syntax=docker/dockerfile:1
################################################################################

FROM php:8.3.12-apache as final

# enable Rewrites and setup mysqli, pdo, and xdebug
RUN a2enmod rewrite \
    && apt-get update && apt-get install -y libmariadb-dev \
    # Install and enable mysqli and pdo_mysql extensions
    && docker-php-ext-install mysqli pdo_mysql \
    && docker-php-ext-enable mysqli pdo_mysql \
    # Install and enable xdebug
    && pecl install xdebug-3.4.1 \
    && docker-php-ext-enable xdebug \
    # Move production php.ini and configure xdebug
    && mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" \
    && { \
        echo "xdebug=true"; \
        echo "xdebug.mode=debug"; \
        echo "xdebug.client_host=host.docker.internal"; \
        echo "xdebug.start_with_request=yes"; \
        echo "xdebug.log=/dev/stdout"; \
        echo "xdebug.log_level=3"; \
    } >> "$PHP_INI_DIR/php.ini"


USER www-data

compose.yaml

services:
  server:
    build:
      context: .
    ports:   ["9000:80"]
    volumes: ["./htdocs:/var/www/html"]

  db:
    image:   mariadb
    restart: always
    environment:
      MARIADB_ROOT_PASSWORD: geheim

  adminer:
    image:   adminer
    restart: always
    ports:   ["8080:8080"]

Starting

Start with docker compose up --build end with Ctrl+C.

Debugging

Browser setup

Needs a xdebug extension.

VSCode

Needs xdebug - plugin.

configure XDebug plugin with a launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Listen for Xdebug",
            "type": "php",
            "request": "launch",
            "port": 9003,
            "pathMappings": {
                "/var/www/html": "${workspaceFolder}/htdocs"
            }
        }
    ]
}

Adjust

If it works you might want to tone down the level of xdebug logging with this added to the Dockerfile

RUN echo "xdebug.log_level=3" >> "$PHP_INI_DIR/php.ini"
Sign up to request clarification or add additional context in comments.

2 Comments

So no more issues, right? as I was planning to work on the setup
yes it works for me: put this in a small repo

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.