关键词:Docker、Electron、NapCat、NTQQ、端口映射、bridge 网络、假监听、容器网络排障


一、问题背景

在一台 Linux 服务器上,我通过 Docker Compose 部署了 NapCat + LangBot,其中:

  • NapCat 运行在 Docker 容器中

  • 使用 bridge 网络模式

  • 显式映射了多个端口,例如:

ports:
  - 6099:6099
  - 3001:3001

预期行为
同一局域网内的其他机器,可以通过 http://宿主机IP:6099 访问 NapCat Web UI。

实际行为

  • 本机访问 localhost:6099

  • 局域网访问 宿主机IP:6099

  • 非容器服务端口访问正常 ✅

  • 使用 network_mode: host 后一切正常 ✅

  • 更离谱的是:一个没有映射的 6100 端口,反而可以访问


二、问题现象复盘(非常关键)

curl 访问结果

局域网 Windows 机器访问容器端口:

curl -v http://192.168.31.50:3001/
# 连接超时

访问非容器服务端口:

curl -v http://192.168.31.50:2017/
# HTTP 200 OK

排除:

  • 局域网问题

  • 路由问题

  • 防火墙问题


Docker 显示端口“已映射”

docker ps

显示:

0.0.0.0:6099->6099/tcp
0.0.0.0:3001->3001/tcp

看起来一切正常


NapCat 容器日志显示“监听成功”

[NapCat] [WebUi] WebUi User Panel Url: http://127.0.0.1:6099/webui
[NapCat] [WebUi] WebUi User Panel Url: http://0.0.0.0:6099/webui

到这里为止,所有“表面证据”都指向:端口已经监听成功

但事实并非如此。


三、关键排障步骤(真相就在这里)

使用 ss 查看宿主机监听端口

ss -lntp | grep napcat

输出:

# 空

这一步非常重要,它说明:

宿主机上,没有任何进程在监听 6099 / 3001


改用端口反查进程(正确姿势)

ss -lntp | grep 6100

结果类似:

LISTEN 0 511 0.0.0.0:6100 users:(("chrome",pid=xxxxx))

破案了。


四、根因分析:什么是“端口假监听”?

NapCat ≠ 真正监听端口的进程

NapCat 的架构本质是:

NapCat (Node / Shell)
 └── NTQQ (Electron)
      └── Chromium 子进程(真正监听 HTTP)

所以:

  • 监听端口的不是 NapCat

  • 而是 Electron / Chromium 子进程


Electron 在 Docker bridge 网络下的致命问题

在以下环境中:

  • Docker

  • bridge 网络

  • 无 GUI

  • 无 DBus

  • 无 GPU / EGL

Electron 会出现以下行为:

  • WebUI 监听逻辑“成功返回”

  • 但底层 bind() 实际失败

  • 监听退化为:

    • 仅 loopback

    • 或监听根本不存在

于是就出现了:
日志显示监听成功,但 OS 层面没有任何端口

这就是本文标题中的:
端口“假监听”


那 6100 是怎么来的?

6100 并不是你映射的端口,而是:

  • Electron / Chromium

  • 自动启动的:

    • DevTools

    • 内部管理面板

    • 调试 Web Server

特点:

  • 直接监听在宿主机网络栈

  • 不走 Docker ports

  • 不受 compose 配置控制

  • 端口可能每次启动变化

这也是为什么:

❓ 我没映射 6100,但它能访问
✅ 因为它根本不在 Docker NAT 体系里


五、为什么 host 网络模式能“秒解决”?

network_mode: host

这意味着:

  • 容器 = 宿主机网络命名空间

  • Electron 不再感知“容器网络”

  • 所有监听行为都回归正常

对于 Electron / NTQQ / QQ 这类应用来说:

host 网络不是妥协,而是正确用法


六、总结:用一句话讲清整个问题

这不是 Docker 的端口映射问题,而是 Electron 应用在 Docker bridge 网络下,WebUI 监听行为不可靠,导致“日志成功、系统无监听”的端口假监听现象。


七、最终建议(血的教训)

强烈推荐

network_mode: host

适用于:

  • NapCat

  • NTQQ

  • Electron

  • Chromium

  • 各类“桌面套壳 Web 应用”


不建议继续浪费时间的方向

  • iptables / firewalld

  • Docker 端口映射反复修改

  • curl / telnet 怀疑人生

  • frp / nginx 硬转发


八、写在最后

这类问题:

  • 日志不会报错

  • Docker 看起来完全正常

  • 只有从 OS 层 ss / lsof 才能看出真相

如果你正在容器化 Electron 应用:

一定要警惕 bridge 网络下的“端口假监听”