You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调试Docker应用时Xdebug在curl_exec处挂起的问题排查

问题描述

我在Windows11上用Docker部署了包含REST API的网站,使用NetBeans配合Xdebug 3调试。非调试状态下网站运行正常,但调试时,执行到curl_exec调用同服务器API的代码时,程序无报错挂起,即使删除所有断点也会出现该问题。用WAMPServer调试一切正常,Postman调用API也无异常。

我的配置如下:

php.ini中的Xdebug 3配置

# Xdebug 3
xdebug.mode=debug

# Client stuff
xdebug.discover_client_host=1
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.idekey="netbeans-xdebug"

# Making sure we have some time
xdebug.connect_timeout_ms = 6000

;xdebug.log_level : 0 Criticals, 1 Connection, 3 Warnings, 5 Communication, 7 Information, 10 Debug Breakpoint
xdebug.log_level=7
xdebug.log=/var/log/xdebug/xdebug.log

# Some error and log settings
xdebug.force_display_errors=1
xdebug.show_error_trace=1
xdebug.show_exception_trace=1
xdebug.show_local_vars=0

Docker Compose web服务配置

# This is the container for the Apache server
web:
  # The location of the Dockerfile
  build:
    context: './bin/php'
    
  # A file containing sensitive information
  env_file: ".env"
    
  # The name for this container
  container_name: "server"
  
  # If anything goes wrong, restart the web server
  restart: "always"
  
  # Using both port 80 on the host and the container
  ports:
    - "80:80"
    
  # We want the database to be started before the server can start
  depends_on:
    - database
    
  volumes:
    # The 'web' directory will be mapped to the container directory "/var/www"
    - ./web:/var/www
    - ./settings.conf:/var/settings.conf
    
    # These are config files mapped to the VMs config files
    - ./config/php/php.ini:/usr/local/etc/php/php.ini
    - ./config/vhosts:/etc/apache2/sites-enabled
    
    # These are log directories mapped to the VMs log directories
    - ./logs/apache2:/var/log/apache2
    - ./logs/xdebug:/var/log/xdebug
    
  environment:
    # Settings for the Apache webserver
    APACHE_DOCUMENT_ROOT: /var/www
    
    # Settings for phpMyAdmin
    PMA_PORT: 8080
    
    # Settings for the MySQL database
    MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
    MYSQL_USER: ${MYSQL_USER}
    MYSQL_PASSWORD: ${MYSQL_PASSWORD}
    MYSQL_DATABASE: database
    HOST_MACHINE_MYSQL_PORT: 3306
    
    # Settings for XDEBUG
    XDEBUG_CONFIG: "client_host=host.docker.internal remote_port=9003"
    
  extra_hosts:
    - "host.docker.internal:host-gateway"

网站Dockerfile基于PHP:8.2-apache镜像构建,已安装Xdebug。

解决方案

这个问题的核心是:调试主请求时,curl_exec发起的同服务器API请求也触发了Xdebug调试,而IDE默认只能处理一个调试连接,导致子请求等待IDE响应,进而整个程序挂起。

可以通过以下几种方式解决:

  1. 限制Xdebug仅在手动触发时启动
    修改php.ini中的xdebug.mode和xdebug.start_with_request:

    xdebug.mode=develop,debug
    xdebug.start_with_request=trigger
    

    这样只有当请求中包含XDEBUG_SESSION=netbeans-xdebug参数(或IDE自动添加的调试Cookie)时,Xdebug才会启动调试。curl发起的内部请求不会自动触发调试,避免阻塞。

  2. 在curl请求中禁用Xdebug
    若不想修改全局配置,可在curl请求里添加XDEBUG_SESSION=off的Header,强制关闭子请求的Xdebug:

    $ch = curl_init('http://your-api-url');
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['XDEBUG_SESSION: off']);
    // 其他curl配置
    $response = curl_exec($ch);
    
  3. 检查Xdebug日志确认问题
    查看/var/log/xdebug/xdebug.log,如果发现有两个调试连接请求(主请求和curl的子请求),即可确认是该原因。日志里会有类似Connecting to configured address/port: host.docker.internal:9003的重复条目。

  4. 统一Xdebug配置,避免冲突
    Docker Compose的XDEBUG_CONFIG环境变量和php.ini中的配置重复,建议只保留一处配置,比如删除php.ini中的xdebug.client_host和xdebug.client_port,用环境变量统一控制,避免配置冲突。

内容的提问来源于stack exchange,提问作者Zoë van den Berg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 17:30:59