初始问题:
用户在 Mac 电脑上无法通过 curl http://192.168.2.4:2343/ 访问在 Windows 电脑的wsl中 Docker 中运行的 PhotoPrism 服务,报错 Couldn't connect to server。然而,在 Windows 本机上 curl localhost:2343 是成功的。

排查过程与发现:

  1. 确认基本网络连通性 (Mac 到 Windows IP):

    • 操作: 在 Mac 上 ping 192.168.2.4
    • 发现: ping 成功,显示有数据包往返。
    • 结论: 排除了 Mac 和 Windows 电脑之间基本的 IP 层网络连通性问题。
  2. 检查 Windows 防火墙:

    • 操作: 用户确认 Windows 防火墙已关闭。
    • 发现: 防火墙没有阻止连接。
    • 结论: 排除了 Windows 防火墙阻止外部连接的可能性。
  3. 确认 Docker 端口映射及本地可访问性:

    • 操作: 用户之前确认 docker ps 输出显示 0.0.0.0:2343->2342/tcp,且在 Windows 本机 curl localhost:2343 成功。
    • 发现: Docker 容器正在运行,并通过端口映射在 Windows 本机 localhost 上可用。
    • 结论: PhotoPrism 服务本身运行正常,且在 Windows 本机上可访问。问题在于从外部 IP 访问。
  4. 检查现有 netsh 端口代理规则 (排除干扰):

    • 操作: 在 Windows 上运行 netsh interface portproxy show all
    • 发现: 没有针对端口 2343netsh 规则存在。
    • 结论: 排除了现有 netsh 规则可能与 Docker 端口映射冲突或干扰的可能性。
  5. 诊断 Windows 电脑上端口 2343 的监听情况 (核心发现):

    • 操作:
      • 在 Windows 上运行 netstat -ano | findstr :2343
      • 根据 netstat 结果中的 PID (16440),运行 tasklist | findstr 16440
    • 发现:
      • netstat 显示 127.0.0.1:2343[::1]:2343 处于 LISTENING 状态。
      • tasklist 显示 PID 16440 对应的进程是 wslrelay.exe
    • 结论: 尽管 Docker 映射显示 0.0.0.0,但在 Docker Desktop 结合 WSL2 的特定环境下,实际 PhotoPrism 服务(通过 wslrelay.exe 代理)只在 Windows 主机的 localhost (127.0.0.1) 接口上监听端口 2343,而没有在 192.168.2.40.0.0.0 等外部可访问的接口上监听。这是导致 Mac 无法连接的根本原因。

解决方案:

  • 措施: 在 Windows 电脑上添加一条 netsh 端口转发规则。
    netsh interface portproxy add v4tov4 listenport=2343 listenaddress=192.168.2.4 connectport=2343 connectaddress=127.0.0.1
    
    这条规则将所有发往 Windows 电脑 192.168.2.4 IP 地址端口 2343 的流量,转发到 Windows 电脑本地回环地址 127.0.0.12343 端口。
  • 结果: Mac 电脑现在可以成功通过 http://192.168.2.4:2343/ 访问 PhotoPrism 服务。

总结性根源与解决思路:
根源: Docker Desktop 在 WSL2 后端运行时,其端口映射(即使是 0.0.0.0)可能不会直接将服务暴露在 Windows 主机的所有外部 IP 地址上,而是通过 wslrelay.exe 仅将其暴露在 localhost 上。
解决思路: 利用 Windows 自带的 netsh interface portproxy 功能,在操作系统层面实现一个端口转发,将外部 IP 上的请求重定向到内部 localhost 上的监听服务。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐