Docker端口已发布却访问不到
容器显示 running,docker ps里也出现了端口,电脑却打不开服务,先把两层端口分开:用户访问的是宿主机端口,应用实际监听的是容器内端口。端口发布不会替应用启动监听。
本文按 Ubuntu 24.04、Docker Engine 28 及以上的常规 rootful 安装、Compose 和普通 bridge 网络的默认 NAT 模式排查,以单个 web服务、宿主机 8080 转容器 TCP 80 为例。不适用于 rootless、host 网络、Swarm 或专门配置的直连路由模式。

宝乐云文档示意:端口为示例值,实际映射、监听和访问范围都要分别核对。
先读正在运行的映射,别只看配置文件
在实际 Compose 项目目录执行,web替换为服务名:
docker compose ps -a
docker compose logs --tail 80 web
docker compose port --protocol tcp web 80
容器若已退出或不停重启,先处理启动错误。只有 80/tcp这样的提示,没有宿主机地址与端口映射,不代表外部已经能访问;Dockerfile 的 EXPOSE 或 Compose 的 expose 也不会自动发布到宿主机。
| ports 写法 | 本例含义 |
|---|---|
8080:80 |
宿主机 8080 转容器 TCP 80;未指定绑定地址,需按对外暴露的端口管理。 |
127.0.0.1:8080:80 |
只给宿主机本地访问,适合同机 Nginx 反向代理;外部电脑不能直接连这个入口。 |
8080:80/udp |
只发布 UDP,不能拿它测试本例的 HTTP/TCP 服务。 |
还要核对 IPv4、IPv6 的实际绑定。这里只演示 IPv4;不要看到其中一种地址正常,就认定另一种地址也已开放。较旧的 Docker 版本应先核对版本与已知限制,不能套用本文的回环绑定边界。
容器里监听127.0.0.1,和宿主机不是一回事
容器有自己的网络空间。应用只监听容器内的 127.0.0.1:80时,映射到容器网络接口的请求通常进不去;本例应按应用支持的方式监听容器接口,例如 0.0.0.0:80。是否对公网开放,仍由宿主机发布地址和访问规则决定。
容器镜像没有 ss 等工具时,可由管理员在宿主机使用已有的 nsenter和ss查看目标容器的网络空间。下面只读取监听,不修改容器;本例服务只有一个运行实例:
port_container_id=$(docker compose ps -q web) &&
test -n "$port_container_id" &&
port_container_pid=$(docker inspect --format '{{.State.Pid}}' "$port_container_id") &&
test "$port_container_pid" -gt 0 &&
sudo nsenter --target "$port_container_pid" --net ss -lnt
应能找到 TCP 80,并核对 Local Address 是否只绑定回环。命令停在前置检查、进程已退出或工具不存在时,先处理对应原因,不把空输出当作网络故障证明。应用实际监听 3000 时,映射右边也要改成 3000;改宿主机端口不能改变应用端口。
按“本机、外部”两次测试缩小范围
先在服务器宿主机做直连检查。-q必须作为第一个参数,跳过 curl 默认配置;--noproxy '*'让本次请求不使用终端代理。下面适用于前表中前两种绑定;如果只发布到指定的其他宿主机地址,应改用那个实际地址:
curl -q --noproxy '*' -i --max-time 5 http://127.0.0.1:8080/
然后在自己的电脑直连公网入口,同样排除代理与默认配置影响。203.0.113.10是示例地址,必须替换;Windows PowerShell 中把 curl改为 curl.exe,其余参数保持不变:
curl -q --noproxy '*' -i --connect-timeout 5 --max-time 10 http://203.0.113.10:8080/
- 本机也失败:继续查容器状态、应用监听、映射左右端口和 HTTP/HTTPS 协议。
- 本机成功、外部失败:核对是否故意只绑定回环,以及公网入口、TCP 协议和允许来源;云侧设置见安全组操作教程。
- 收到401、403或404:说明某个 HTTP 服务有响应,还要对照目标应用日志和返回内容,不能只凭状态码确认命中了正确容器。
在 Ubuntu 上,Docker 发布流量可能在进入 UFW 常规处理前就被转发,不能仅凭 ufw status判断容器的暴露范围。保留 Docker 自建规则,按实际防火墙后端检查;不要关闭整套防火墙,或把 Docker 的 iptables 功能关闭来试运气。
改端口后需要重建,restart不会应用新映射
普通网站由同机 Nginx 接入时,可在原有 web 服务内保留下面的回环发布字段,再按反向代理教程接入域名。这里只是字段片段,不用它替换整个 Compose 文件:
ports:
- "127.0.0.1:8080:80"
保存原配置、确认镜像版本和数据挂载后,在维护窗口应用。该操作可能重建 web,先按数据卷与目录挂载教程确认数据不依赖容器可写层:
docker compose config -q &&
docker compose up -d --no-deps --pull never --no-build web
随后重跑 port、监听检查和实际入口测试;如果设计为只供本机代理,就从域名入口验收,外部直连 8080 不通是预期结果。重建出错时保留错误和原配置,按应用更新与回退教程处理,不用 down -v清理数据卷。