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

Docker环境下PHP使用stream_socket_client连接SMTP超时求助

问题描述

我开发了一个PHP应用,通过代理建立与邮件服务器(SMTP服务器)25端口的TCP套接字连接,核心代码如下:

$context = [
    "http" => [
        "proxy" => "tcp://xx.xx.xx.xx:xxxx",
        "request_fulluri" => true 
        "header" => "Proxy-Authorization: Basic xxxxxxxxxxx"
    ]]
};

$connection = @stream_socket_client(
        address: "tcp://$mxHost:25",
        error_code: $errno,
        error_message: $errstr,
        timeout: 10,
        context: $context
);

最初版本是包含部分Symfony组件的原生PHP应用,使用php -S localhost:8000 -t .运行时一切正常。

之后迁移至Docker环境下的完整Symfony应用(基于DDD/整洁架构,迁移过程无问题),但Docker内无法正常使用stream_socket_client,始终出现连接超时(错误码110)。

曾在docker-compose.yml中添加自定义DNS配置:

dns:  # Custom DNS settings
      - 8.8.8.8
      - 1.1.1.1

问题曾解决一天,但次日又恢复连接超时状态。

排查与解决建议
  • 修正代码语法问题:你提供的上下文数组里,"request_fulluri" => true末尾缺少逗号,这会导致PHP语法解析错误。虽然本地运行正常可能是粘贴笔误,但Docker环境下的语法检查更严格,先修正这个问题再测试。
  • 验证容器到代理的连通性:进入Docker容器内部,执行telnet xx.xx.xx.xx xxxx或nc -zv xx.xx.xx.xx xxxx,测试能否直接连通代理服务器。如果连不通,排查宿主机防火墙规则、Docker网络模式限制(比如bridge模式的端口策略)、代理服务器的IP白名单是否排除了容器IP段。
  • 确认DNS解析稳定性:在容器内手动解析目标SMTP服务器域名,执行nslookup $mxHost或dig $mxHost,观察解析结果是否稳定,有没有出现解析失败或返回错误IP的情况。同时可以重启容器或Docker服务,清除DNS缓存。
  • 测试代理配置有效性:在容器内用curl验证代理是否可用,比如执行curl -x tcp://xx.xx.xx.xx:xxxx -U 用户名:密码 http://example.com(替换为你的代理凭据),确认代理能正常转发请求。
  • 优化socket连接参数:去掉@错误抑制符,打印完整的$errno和$errstr信息,获取更详细的错误细节;尝试延长超时时间(比如改为30秒),排查是否是网络延迟导致的超时。
  • 切换Docker网络模式测试:如果用默认bridge模式,临时改为host模式(在docker-compose.yml中添加network_mode: host),测试是否能正常连接。注意host模式会让容器共享宿主机网络,仅用于排查网络隔离问题,生产环境谨慎使用。
  • 检查防火墙与安全组规则:确认宿主机的iptables/ufw是否限制了容器对外的25端口访问;如果是云服务器,检查云服务商的安全组是否允许容器IP段的25端口出站流量。
  • 核对Symfony环境配置差异:对比原生PHP和Symfony应用的php.ini配置,检查allow_url_fopen、stream_socket_client相关参数是否被覆盖;查看Symfony的环境变量,确认没有影响网络连接的配置项。

内容的提问来源于stack exchange,提问作者friday-json

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 14:12:34