-p 的几种写法到底差在哪?只想让本机访问怎么写?-P 的随机端口从哪来?映射的端口在 Mac 上是谁在监听?这篇逐项实测,包括端口冲突时容器的状态。
-p 9780:8000:docker port → 0.0.0.0:9780
[::]:9780;docker ps 的 PORTS 列 → 0.0.0.0:9780->8000/tcp, [::]:9780->8000/tcp
Mac 访问 127.0.0.1:9780 → hello from container
Mac 用局域网地址访问 <本机局域网IP>:9780 → hello from container
-p 127.0.0.1:9790:8000:docker port → 127.0.0.1:9790
Mac 访问 127.0.0.1:9790 → hello from container
Mac 用局域网地址访问 <本机局域网IP>:9790 → URLError:[Errno 61] Connection refused-p 9780:8000 没写地址就是所有地址(0.0.0.0 和 [::]),局域网里的其它机器也能访问;-p 127.0.0.1:9790:8000 只在本机回环地址上监听,用局域网地址访问被拒绝。要对外暴露还是只给本机,在这里决定。
docker port → 8000/tcp -> 0.0.0.0:55000 ; 9000/udp -> 0.0.0.0:55000 随机的宿主机端口 55000(落在 32768 以上吗?True),Mac 访问 → hello from container
-P 把 Dockerfile 里 EXPOSE 声明的所有端口映射到随机的宿主机端口(这次 TCP 和 UDP 拿到了同一个 55000)。docker port 能查到。
Mac 发 UDP "ping" 到 127.0.0.1:9800 → udp-echo:ping 只写 -p 9800:9000(不带 /udp)时 docker port → 9000/tcp -> 0.0.0.0:9810 9000/tcp -> [::]:9810
UDP 要写 /udp,否则按 TCP 映射。回显测试证实 UDP 可以双向通。
lsof -iTCP:9780 -sTCP:LISTEN:com.docke 71668 虚拟机里有这个端口在监听吗?LISTEN 0 4096 0.0.0.0:9780 0.0.0.0:*
在 macOS 的 Docker Desktop 上,Mac 里监听映射端口的是 Docker Desktop 自己的进程(lsof 显示 com.docke…),虚拟机里的 0.0.0.0:9780 也在监听,请求经这两层转发给容器。Linux 宿主机上通常是 docker-proxy 或 iptables 规则,我没有测。
同一个宿主机端口再映射一次:退出码 125;docker: Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint bwlab 失败的容器处于什么状态?created
宿主机端口已被占用时,docker run 以 125 退出,容器停在 created 状态,需要手动删除。