EXPOSE 与端口发布
EXPOSE 只是镜像里的声明性元数据,用来告诉使用者应用打算监听哪个端口,它本身不建立任何映射;真正让宿主机端口对外可用的是 -p 或 -P。把两者混为一谈,是端口为什么不通这类问题的头号来源。
基本信息
| EXPOSE | 镜像元数据,声明应用监听端口,不做映射 |
|---|---|
| -p 8080:80 | 建立映射并让宿主机监听 8080,转发到容器 80 |
| -P | 把镜像中所有 EXPOSE 端口随机发布到宿主机 |
| 容器间通信 | 同一自定义网络内按容器名加容器端口直连 |
| 访问范围 | 不写 -p 时容器端口只能从 Docker 网络内部访问 |
| 验证 | docker port 与 inspect 的端口字段 |
三种写法的效果
| 写法 | 作用 | 典型误区 |
|---|---|---|
| EXPOSE 80 | 仅声明元数据 | 以为写了就对外可用 |
| -p 8080:80 | 宿主机 8080 映射到容器 80 | 漏加 -p 仍不通 |
| -p 127.0.0.1:8080:80 | 只绑本机回环 | 忘记绑定地址导致全机暴露 |
| -P | 随机分配宿主端口 | 依赖固定端口却用了 -P |
核对思路
核对思路
docker port web # 查看已发布端口
docker inspect web -f '{{json .NetworkSettings.Ports}}' # 看映射详情
ss -lntp | grep 8080 # 宿主是否真的在监听
docker exec web ss -lntp # 容器内应用是否在监听典型使用场景
- 排查容器端口不通,先分清是没发布还是应用没监听
- 部署时决定用固定端口映射还是交给编排工具处理
- 只允许本机访问的调试端口,需要绑定到回环地址
- 多容器互访时避免无谓地把端口暴露到宿主机
未声明 EXPOSE 的端口照样能用 -p 发布;声明了 EXPOSE 但不写 -p 依然不通,两者互不依赖,排查时不要混用结论。
端口映射只改变访问路径,不改变容器内应用监听的地址;应用若只绑回环地址,映射出来同样访问不到。
用 -P 随机发布端口会让宿主机端口漂移,外部依赖与防火墙规则全部对不上,生产环境不要使用。
只在本机调试时把端口绑到回环地址即可,需要外部访问才绑全部网卡;同机多个容器映射同一个宿主端口会直接冲突,报端口已被占用。