登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  软件教程

Docker Compose检查端口与网络解析

来源:17golang原创

时间:2026-11-15 12:09:03 338浏览 收藏

Docker Compose 排查端口和网络时,最容易把两个入口混为一谈:宿主机通过映射后的端口访问服务,容器之间则通过 Compose 服务名和容器端口通信。下面用一个 web 服务和一个 db 服务,把“端口有没有发布”和“服务名能不能解析”拆开检查。

官方地址:https://docs.docker.com/compose/

建议先记住这个例子:8080:80 表示宿主机的 8080 转到容器的 80;8001:5432 表示宿主机的 8001 转到容器的 5432。容器内的 web 访问数据库时,应使用 db:5432,而不是 localhost:8001。

先准备一个能观察的 Compose 项目

在项目目录创建 compose.yaml。这里不把它当作生产配置,而是专门用来观察端口映射和默认网络中的服务发现。

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80" # 宿主机访问 8080,容器内服务监听 80
    networks:
      - app-net

  db:
    image: postgres:latest
    ports:
      - "8001:5432" # 宿主机访问 8001,容器内数据库端口是 5432
    networks:
      - app-net

networks:
  app-net:
    driver: bridge # 让 web 和 db 进入同一个 Compose 网络

在项目目录的命令入口执行:

# 启动 compose.yaml 中声明的服务,并在后台运行
docker compose up -d

可见状态应是两个服务都处于运行中。若某个服务没有启动,先看服务状态,不要直接把问题归因于 DNS 或端口。

从状态表确认宿主机端口

在项目目录打开“Compose 项目 → 服务状态”入口,先执行 docker compose ps。它会列出服务、当前状态和公开端口;端口列出现 0.0.0.0:8080->80/tcp 时,左侧是宿主机端口,右侧是容器端口。

# 只查看当前项目的运行状态和端口映射
docker compose ps

# 包括已经停止的容器,排查服务是否启动后又退出
docker compose ps --all
Compose 服务状态与 8080 到 80、8001 到 5432 端口映射的原创说明图
图1:操作示意图,查看 Compose 服务状态和端口映射;这是原创界面说明图,不是运行截图。

这一步的确认点有三个:web 和 db 是否为运行状态;端口映射是否与 compose.yaml 一致;协议是否为预期的 tcp。宿主机访问数据库时使用 localhost:8001,不要把容器端口 5432 直接当成宿主机端口。

用 compose port 精确查询单个映射

如果状态表信息较多,可以在“服务状态 → 端口查询”入口单独查询某个服务的容器端口。命令格式是 docker compose port SERVICE PRIVATE_PORT:

# 查询 web 服务容器 80 端口对应的公开端口
docker compose port web 80

# 查询 db 服务容器 5432 端口对应的公开端口
docker compose port db 5432

# 多副本服务可指定容器序号;默认协议是 tcp
docker compose port --index 1 db 5432

如果这里查不到映射,通常不是网络解析问题,而是服务没有运行、端口没有写入 ports,或者查询的容器端口与服务实际监听端口不一致。只有对外访问需要 ports;同一 Compose 网络里的服务互访,不需要为了“能解析”而额外发布宿主机端口。

从容器内部检查服务名解析

在“服务状态 → web → 网络诊断”入口执行容器内检查。Compose 默认会创建项目网络,并把服务名注册到内部 DNS;因此检查重点应该从 web 容器内部发起。

# -T 关闭伪终端,便于把命令用于脚本或自动化检查
docker compose exec -T web getent hosts db

# 用服务名和容器端口检查 web 到 db 的 TCP 连接
docker compose exec -T web sh -c 'nc -zv db 5432'

当第一条命令能解析出 db 的容器地址,说明服务名解析已建立;第二条命令能连通时,才说明网络路径和数据库监听端口也基本匹配。这里的地址应写成 db:5432。localhost 在 web 容器里指向的是 web 自己,不是宿主机,也不是 db。

Compose 网络中 web 解析 db 服务名并区分 db:5432 与 localhost:8001 的原创说明图
图2:结果示意图,区分容器内服务名解析与宿主机端口访问;这是原创界面说明图。

按网络边界定位连接失败

把失败点放回访问边界,排查会更快:

访问场景应使用的地址优先检查
浏览器或宿主机访问 weblocalhost:8080ports、docker compose ps
宿主机工具访问 dblocalhost:8001宿主机端口是否被占用、映射是否存在
web 容器访问 dbdb:5432服务名、共同网络、容器端口

如果两个服务没有加入同一个自定义网络,先检查服务级 networks 是否都包含 app-net。如果配置了 network_mode: host,容器会共享宿主机网络栈,端口映射和服务名 DNS 的判断方式都会改变,不要继续套用默认 bridge 网络的结论。

# 查看 Compose 最终识别到的服务,排除文件路径或服务名写错
docker compose config --services

# 完成排查后停止并移除本次示例创建的服务
docker compose down

常见问题

为什么 ps 显示 Up,但宿主机访问不了?

先看 ports 是否存在,再用 docker compose port 查询容器端口。只有 expose 或仅在容器内监听,并不会自动创建宿主机入口。

为什么容器内不能连接 localhost:8001?

因为容器内的 localhost 指向当前容器。跨服务连接应使用 Compose 服务名和容器端口,也就是本例的 db:5432。

为什么重建容器后旧 IP 失效?

Compose 网络中的容器 IP 可以随重建变化,服务名保持稳定。应用配置应保存服务名,不要把临时容器 IP 写死。

最后可以把排查顺序固定为:先用 docker compose ps 看服务是否运行,再用 docker compose port 看宿主机映射,最后进入调用方容器检查服务名解析。这样能把端口发布、容器端口和网络 DNS 三个问题分开,定位会比反复修改端口号更快。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>