因为 lsof -i :443
不仅显示"谁在监听",还显示"谁在使用这个端口通信"。
✅ 核心原理:Nginx 的多进程架构
Nginx 是 master-worker 模型:
类型 | 数量 | 职责 | 是否监听端口 |
---|---|---|---|
Master 进程 | 1 个(如 PID 1734) | 管理配置、启动 worker、监听端口 | ✅ 监听 |
Worker 进程 | 多个(如 2707653, 2707654...) | 处理客户端请求 | ❌ 不"重新"监听,而是继承 master 的监听套接字 |
🔔 重点:只有 master 进程(或第一个 worker)会"绑定并监听"端口,后续 worker 是通过共享套接字来处理连接的。
✅ 验证方法
你可以用下面命令确认哪个 PID 是主进程:
perl
bash
深色版本
ps aux | grep nginx
输出类似:
yaml
bash
深色版本
root 1734 0.0 0.1 123456 7890 ? Ss 10:00 0:00 nginx: master process /usr/sbin/nginx
www-data 2707653 0.0 0.2 123456 8901 ? S 10:05 0:00 nginx: worker process
www-data 2707654 0.0 0.2 123456 8902 ? S 10:05 0:00 nginx: worker process
master process
是真正绑定端口的那个。worker process
只是处理请求。
✅ 总结
PID | 角色 | 是否导致 address already in use |
原因 |
---|---|---|---|
1734 (master) | 主进程,LISTEN |
✅ 是 | 它绑定了 443 端口 |
2707653+ (worker) | 工作进程,ESTABLISHED |
❌ 否 | 它只是在处理已有连接,不"重新监听" |
🔑 所以我只强调
PID 1734
,是因为它是真正导致端口冲突的源头。终止它(或整个 Nginx 服务),就能释放 443 端口,让 Docker 成功绑定。