Docker 已映射端口,UDP 服务仍收不到请求
Docker 的 -p 默认发布 TCP。分别核对 UDP 与 TCP 映射,在原启动或 Compose 配置中明确 /udp,再重建服务并用应用请求验证。
容器已经启动,docker ps 也显示了宿主机端口,但 UDP 客户端一直收不到响应。仔细看映射,末尾却是 /tcp:例如 12123->2123/tcp。这种情况下,端口号虽然对应正确,发布的传输协议仍与服务不一致。
Docker 的 -p 12123:2123 默认发布 TCP,不会根据应用实际监听的协议自动改成 UDP。以下针对普通 bridge 网络、默认 NAT 模式下的端口发布;不套用于 host 网络、Swarm 服务或直接路由的特殊配置。示例假设应用确实监听容器的 UDP 2123,宿主机使用 12123,实际操作时替换为服务自己的端口。
分别查询 TCP 与 UDP 映射
把 udp_service_container 换成实际容器名或 ID:
docker container port udp_service_container 2123/udp
docker container port udp_service_container 2123/tcp
docker container inspect udp_service_container --format '{{json .NetworkSettings.Ports}}'
第一条若报告 No public port '2123/udp' published,而第二条能列出地址,说明现有容器只发布了 TCP。NetworkSettings.Ports 的键也会区分 2123/tcp 与 2123/udp;UDP 项不存在或没有宿主机绑定,都不能当作已发布。
这里查询的是容器端口 2123,不是宿主机端口 12123。只运行 docker port 容器 2123 容易漏看协议,应显式带上 /udp。这些结果证明映射配置,不证明应用已经正确监听或处理数据。
如果 UDP 映射已经存在,这篇的修复就不对应当前原因。应继续核对应用监听地址、目标端口以及沿途针对 UDP 的规则,不要反复添加同一映射。
在原来的发布配置中补上 /udp
对于 docker run 管理的容器,将原命令的端口参数改为:
-p 127.0.0.1:12123:2123/udp
这是要合并进原启动命令的参数片段,其他镜像版本、环境变量、卷、网络和启动参数应保留。127.0.0.1 用于宿主机本地客户端验证。若客户端在其他机器上,需要按访问范围选择宿主机可达地址,并核对防火墙和上游网络规则;不能指望远程客户端访问宿主机的回环映射。
在 Docker 28.0.0 之前,绑定 localhost 的发布端口存在同一二层网络内其他主机可能访问的边界,不要把这种旧版本配置当作完整隔离措施。省略宿主机 IP 通常会扩大到所有宿主机地址,也不应作为排错的默认改动。
Compose 管理的服务可以只修改其 ports 项。下面是需要合并到现有服务中的片段,不是替代整个 Compose 文件:
services:
udp_service:
ports:
- "127.0.0.1:12123:2123/udp"
长格式的对应字段是 protocol: udp;省略协议时仍默认 TCP。短格式的端口映射保留引号。
如果服务在相同编号上确实同时需要 TCP 和 UDP,分别保留两项:
ports:
- "127.0.0.1:12123:2123/tcp"
- "127.0.0.1:12123:2123/udp"
这会建立两个不同协议的入口,并不把 TCP 数据转换成 UDP。应用只有 UDP 监听时,没有必要为了试错额外发布 TCP。
让新配置作用于容器
修改 Compose 文件后,需要按更新后的配置重建对应服务容器。确认依赖服务已正常运行、持久数据已正确挂载并有备份后,在原 Compose 项目目录执行:
docker compose up -d --no-deps udp_service
把服务名换成实际名称。Compose 会在配置变化时停止并重建该服务的容器,因此应安排允许中断的时间;保存在容器可写层、没有持久化的数据不能依赖重建保留。不要通过 down -v 删除数据卷来处理端口协议问题。
直接用 docker run 管理时,也应按保留的完整启动配置重建,先处理数据与停机安排。仅改 Dockerfile 的 EXPOSE 2123/udp 不会修改现有容器的端口绑定;EXPOSE 是端口用途声明,显式 -p 也不依赖它才能发布。
用应用自己的请求确认修复
重建后再次查询 docker container port ... 2123/udp,应看到计划中的宿主机地址与端口。然后从对应客户端发送该应用支持的 UDP 请求,核对响应或服务端实际接收记录。测试使用宿主机地址与 12123,而不是误连容器端口号。
普通 HTTP 请求或 TCP 连接测试无法验证这条 UDP 映射。映射存在但仍无响应时,保留检查结果,再沿应用监听、网络过滤与客户端协议继续定位,避免把所有无响应都归结为 Docker 发布参数。
回退时恢复之前保存的启动配置或 Compose 版本,并按相同方式重建对应服务。协议映射修复不需要删除镜像、卷或手工清空宿主机防火墙规则。


