1. 问题现象
容器正在运行,容器内部服务也正常监听,但主机无法访问对应端口。
典型现象:
bash
docker ps
容器 PORTS 列为空,或没有显示预期端口映射。
bash
docker port zentao
没有任何输出。
但容器配置中可以看到端口映射:
bash
docker inspect zentao --format '{{json .HostConfig.PortBindings}}'
例如:
json
{"8050/tcp":[{"HostIp":"","HostPort":"8050"},{"HostIp":"","HostPort":"80"}]}
说明容器原本配置了:
text
主机 8050 -> 容器 8050
主机 80 -> 容器 8050
2. 快速判断端口是否真正发布成功
查看运行时端口状态:
bash
docker inspect zentao --format '{{json .NetworkSettings.Ports}}'
正常应类似:
json
{"8050/tcp":[{"HostIp":"0.0.0.0","HostPort":"8050"},{"HostIp":"0.0.0.0","HostPort":"80"}]}
异常情况:
json
{}
说明 Docker 当前没有实际发布端口。
3. 检查主机端口是否被占用
bash
sudo ss -lntp | grep -E ':(80|8050)\b'
如果没有输出,说明主机 80 / 8050 没有被其他进程占用。
如果有输出,需要先停止占用端口的服务或容器。
例如停止无效容器:
bash
docker stop vi_gitlab
docker update --restart=no vi_gitlab
4. 检查容器内部服务是否正常
进入容器:
bash
docker exec -it zentao bash
查看监听端口:
bash
ss -natl
正常应看到类似:
text
LISTEN 0 511 *:8050 *:*
说明容器内部服务正常监听 8050。
如果只监听:
text
127.0.0.1:8050
则外部可能无法访问,需要修改服务监听地址为 0.0.0.0 或 *。
5. 检查容器是否接入 Docker 网络
查看容器网络 IP:
bash
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' zentao
正常应输出类似:
text
10.1.0.3
如果没有任何输出,说明容器没有正常接入 Docker 网络。
6. 检查指定网络中是否有该容器
查看网络列表:
bash
docker network ls
查看目标网络,例如 vinet:
bash
docker network inspect vinet
重点看 Containers 字段中是否包含 zentao。
如果只有其他容器,例如:
text
vi_minio -> 10.1.0.2
但没有 zentao,说明 zentao 没有接入该网络。
7. 修复:重新接入 Docker 网络
如果确认 zentao 没有接入 vinet,执行:
bash
docker network connect vinet zentao
该操作不会重建容器,不会删除容器数据、配置、用户或数据库。
执行后检查:
bash
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' zentao
正常应输出容器 IP,例如:
text
10.1.0.3
再检查端口:
bash
docker port zentao
docker inspect zentao --format '{{json .NetworkSettings.Ports}}'
docker ps
如果恢复正常,应看到类似:
text
8050/tcp -> 0.0.0.0:8050
8050/tcp -> 0.0.0.0:80
8. 验证访问
主机本机测试:
bash
curl -I http://127.0.0.1
curl -I http://127.0.0.1:8050
局域网测试:
bash
curl -I http://192.100.40.131
curl -I http://192.100.40.131:8050
浏览器访问:
text
http://192.100.40.131
http://192.100.40.131:8050
9. 常见根因总结
本次问题的典型链路:
text
容器进程正常
容器内部服务正常
主机端口未被占用
HostConfig.PortBindings 有端口配置
但容器没有接入 vinet 网络
导致容器没有 IP
导致 Docker 无法建立端口发布
导致 docker ps 的 PORTS 为空
导致 docker port 没有输出
关键修复命令:
bash
docker network connect vinet zentao
10. 防止再次发生
检查 docker-compose.yml 是否明确配置网络:
yaml
services:
zentao:
container_name: zentao
networks:
- vinet
ports:
- "80:8050"
- "8050:8050"
restart: unless-stopped
networks:
vinet:
external: true
确认自启动策略:
bash
docker inspect zentao --format '{{.HostConfig.RestartPolicy.Name}}'
建议设置:
bash
docker update --restart=unless-stopped zentao
11. 快速排查命令合集
bash
docker ps
docker port zentao
docker inspect zentao --format '{{json .HostConfig.PortBindings}}'
docker inspect zentao --format '{{json .NetworkSettings.Ports}}'
sudo ss -lntp | grep -E ':(80|8050)\b'
docker exec -it zentao ss -natl
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' zentao
docker network inspect vinet
docker network connect vinet zentao