关键词: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 网络下的“端口假监听”