在服务器上部署 Docker 应用时,经常会遇到一种情况:宿主机上的接口可以正常访问,但把同一个地址填进容器里的应用后,却提示连接被拒绝。
例如,某个接口运行在宿主机的 8080 端口。在服务器终端访问正常,容器中的应用连接下面这个地址却失败:
http://127.0.0.1:8080
问题往往出在地址指向上。
在常规 bridge 网络模式下,容器里的 127.0.0.1 指向当前容器自己。要连接宿主机,需要使用容器能够访问的宿主机地址,同时确认目标服务的监听设置正确。
本文以 Linux 服务器上的 Docker Engine 为例,介绍单容器和 Docker Compose 的配置方法。
1. 先分清:你要访问的是谁?

配置连接地址之前,先确认目标服务运行在哪里。
| 目标服务的位置 | 通常使用的地址 |
|---|---|
| 当前容器内部 | 127.0.0.1:服务端口 |
| 宿主机上的服务 | 配置映射后的 host.docker.internal:服务端口 |
| 同一 Compose 网络中的其他容器 | 服务名:容器端口 |
| 另一台服务器 | 对方可达的 IP 或域名,加对应端口 |
例如,应用与数据库都通过同一个 Compose 项目部署,并且连接到同一个网络,数据库服务名是 db,那么应用通常应连接:
db:3306
这里使用的是数据库容器内部的端口,不需要绕到宿主机的公网 IP。
Docker 的用户自定义网络支持通过容器名称进行通信;常规容器网络则具有自己的网络接口、地址和路由。把这两种场景分清,能减少很多无效排查。
2. 操作前需要准备什么?
本文适用于 Debian、Ubuntu 等 Linux 系统上的常规 Docker Engine 环境,使用 bridge 网络,并通过 docker compose 管理项目。
先在服务器终端确认 Docker 和 Compose 可以使用:
docker version
docker compose version
尚未安装 Docker,可以先参考本站:
注意,本站这篇早期文章中的 Compose 安装部分使用了旧版 docker-compose。本文使用的是插件形式的 docker compose 命令。
如果已经配置 Docker 官方软件源,在 Debian 或 Ubuntu 上可以安装 Compose 插件:
sudo apt-get update
sudo apt-get install -y docker-compose-plugin
docker compose version
如果尚未配置官方软件源,可按 Docker 官方 Compose 插件安装说明处理。
需要准备测试环境,也可以使用莱卡云 Linux 云服务器。应用资源配置应根据实际项目选择,本次连接排查本身不需要额外部署数据库。
查看官网购买链接: https://www.lcayun.com
9折优惠码:bloglcayun
下面的示例假设:宿主机上已经有一个 HTTP 服务,使用 8080 端口。 请按实际情况替换端口及接口路径。
3. 先检查宿主机服务的监听地址
在服务器终端执行:
sudo ss -lntp '( sport = :8080 )'
重点看监听地址。
只监听127.0.0.1:8080
这表示服务只接受宿主机自身回环地址上的连接。
普通 bridge 容器访问宿主机的网桥地址时,无法直接连接这个只监听 127.0.0.1 的服务。
即使已经添加 host.docker.internal 映射,这个问题也不会自动解决。
需要根据目标应用的配置方式,调整它的监听地址,使其监听容器能够到达的宿主机接口。
监听0.0.0.0:8080
这表示服务监听所有 IPv4 接口,通常具备从容器访问的监听条件,但最终是否能够连接,还取决于路由和防火墙。
0.0.0.0 也可能让服务在公网接口上接受连接。因此,如果服务只供本机容器使用,应优先绑定合适的内部接口,并限制允许访问的来源。
客户端连接地址不要填写 0.0.0.0,它在这里表示服务端的监听范围。
如果命令没有显示监听记录,先确认服务已经启动,以及实际使用的端口是否正确。
4. 使用docker run测试宿主机连接
Linux Docker Engine 可以通过 --add-host 增加地址映射:
docker run --rm \
--add-host host.docker.internal:host-gateway \
curlimages/curl:latest \
--verbose \
--noproxy '*' \
--connect-timeout 5 \
--max-time 10 \
http://host.docker.internal:8080/
这条命令会启动一个临时 curl 容器,向宿主机的 8080 端口发送 HTTP 请求,执行结束后自动删除该测试容器。
其中:
host.docker.internal:供容器使用的宿主机名称。host-gateway:由 Docker 解析为宿主机侧地址的特殊值。--noproxy '*':让这次测试直接连接目标,避免绕经 HTTP 代理。--connect-timeout 5:连接建立阶段最多等待 5 秒。--max-time 10:整个请求最多等待 10 秒。
Docker 官方文档提供了相同的宿主机地址映射方式。Docker Desktop 通常已提供 host.docker.internal 解析,Linux Docker Engine 则可以显式添加上述映射。
测试时需要区分两件事:
收到 HTTP 响应,说明请求已到达某个 HTTP 服务;业务是否正常,还要看状态码和响应内容。
例如,返回 401 可能是缺少登录凭据,返回 404 可能是请求路径不正确,都不能直接判断为网络不通。
这里的 curl 命令用于测试 HTTP 服务。数据库、Redis 等其他协议,应使用对应客户端验证。
5. Docker Compose怎么配置?
使用 Compose 时,在发起请求的服务下面添加 extra_hosts:
extra_hosts:
host.docker.internal: "host-gateway"
这项配置会为容器增加主机名映射。它不会自动修改应用原来填写的接口地址。
如果应用原来的地址是:
http://127.0.0.1:8080
还需要在应用配置中改成:
http://host.docker.internal:8080
独立测试示例
下面提供一个完整的 Compose 检测配置。建议放在单独的测试目录中,不要覆盖现有业务项目的配置文件。
在服务器终端执行:
mkdir -p ~/docker-host-check
cd ~/docker-host-check
cat > compose.yaml <<'EOF'
services:
host-check:
image: curlimages/curl:latest
extra_hosts:
host.docker.internal: "host-gateway"
command:
- "--verbose"
- "--noproxy"
- "*"
- "--connect-timeout"
- "5"
- "--max-time"
- "10"
- "http://host.docker.internal:8080/"
EOF
检查配置并运行:
docker compose config --quiet
docker compose run --rm host-check
检测容器执行完成后退出是正常现象,因为它只负责发送一次请求。
这个示例可以帮助验证 Compose 环境下的访问情况。实际业务容器仍需配置自己的 extra_hosts,并使用正确的接口地址;独立测试成功不代表业务容器的网络与配置一定相同。
修改业务配置后怎么生效?
把 extra_hosts 加入实际业务服务,并修改接口地址后,在该业务项目目录执行:
docker compose up -d
Compose 会根据配置变化更新相关容器,发生重建时可能短暂中断服务。
不要只执行 docker compose restart。官方文档明确说明,单纯重启不会应用 Compose 文件中的配置变更。
6. 配置后仍然连不上,怎么判断原因?
可以先根据错误类型缩小范围。
| 现象 | 优先检查 |
|---|---|
Could not resolve host | 当前容器是否添加了映射,主机名是否拼写正确 |
Connection refused | 目标地址和端口是否正确,服务是否监听该地址,防火墙是否主动拒绝连接 |
| 连接阶段超时 | 路由是否可达,防火墙是否丢弃连接,服务所在主机是否正常 |
| 已连接但等待响应超时 | 接口处理是否阻塞,后端依赖是否异常 |
返回 401 或 403 | 认证信息、访问权限或应用访问规则 |
返回 404 | 接口路径、反向代理路由或 Host 匹配 |
| 宿主机能访问,容器不能访问 | 宿主机测试是否用了回环地址,以及容器网络与防火墙规则 |
排查时建议按下面的顺序进行:
- 确认目标服务运行在宿主机,还是另一个容器。
- 确认宿主机的目标端口确实存在监听。
- 确认服务监听的地址包含容器实际访问的宿主机地址。
- 确认映射已经应用到发起请求的容器。
- 检查防火墙、认证信息和接口路径。
如果容器连外部网站、公共域名也失败,可以继续参考本站:
外网 DNS 故障与宿主机服务只监听回环地址,属于不同问题,处理方式也不同。
7. 两个容易踩坑的地方
不要把宿主机地址固定理解为172.17.0.1
不少示例会直接使用:
172.17.0.1
这个地址在部分默认环境中成立,但 Docker 的地址段和网桥配置可能发生变化。
host-gateway 默认使用默认网桥的宿主机侧地址,也可以由 Docker 守护进程配置覆盖。它不一定是当前 Compose 网络的网关,更不能保证始终是 172.17.0.1。
因此,使用明确的主机名映射通常更便于维护。
不要把host网络当成通用修复方法
Linux 下使用 network_mode: host 时,容器共享宿主机网络空间,此时回环地址的含义与普通 bridge 容器不同。
但这会改变网络隔离方式,端口也直接占用宿主机端口,原有的端口映射不再起作用。应在理解这些变化后再使用。
本文的配置方法针对常规 bridge 网络。Rootless Docker、Docker Desktop 和特殊网络驱动的访问行为,应结合各自环境判断。
8. 结语
Docker 容器访问宿主机时,最关键的是同时确认三个条件:地址指向正确、服务监听正确、网络允许连接。
host.docker.internal 配合 host-gateway 可以解决宿主机地址映射问题;服务的监听地址和防火墙规则,则决定请求能否真正到达目标。
如果目标其实是同一 Compose 网络中的其他容器,优先使用服务名和容器端口。先分清服务的位置,再按错误类型排查,配置会清楚得多。








