host-gateway
是 Docker 从 20.10 版本开始引入的一个特殊保留关键字(reserved keyword),用于在容器中访问宿主机(Host Machine)的服务。它在配置网络时非常有用,尤其是在使用 --add-host
或 docker-compose.yml
的 extra_hosts
时。
🔍 一、什么是 host-gateway
?
host-gateway
并不是一个真实的 IP 地址,而是一个由 Docker 自动解析的占位符,代表:
宿主机在 Docker 内部网络中的网关地址(通常是
docker0
虚拟网桥的 IP,如172.17.0.1
)。
当你在 Docker 容器中需要访问运行在宿主机上的服务(如数据库、API、Redis 等),就可以通过 host-gateway
来指向宿主机。
🧩 二、为什么需要 host-gateway
?
在默认情况下,Docker 容器运行在一个隔离的网络命名空间中:
- 容器的
localhost
指的是容器自己,不是宿主机。 - 宿主机的
127.0.0.1
对容器不可见。
因此,如果宿主机上运行了一个服务(比如监听在 0.0.0.0:3306
的 MySQL),容器无法通过 localhost:3306
访问它。
解决方法就是:告诉容器“宿主机的 IP 是多少” —— host-gateway
正是为此而生。
✅ 三、如何使用 host-gateway
?
1. 在 docker run
中使用
docker run --add-host=host.docker.internal:host-gateway \
-it myapp:latest
这会在容器的 /etc/hosts
中添加一行:
<host-gateway-ip> host.docker.internal
例如:
172.17.0.1 host.docker.internal
然后在容器内就可以通过 host.docker.internal
访问宿主机服务:
curl http://host.docker.internal:8080
ping host.docker.internal
2. 在 docker-compose.yml
中使用
version: '3.8'
services:
app:
image: myapp:latest
extra_hosts:
- "host.docker.internal:host-gateway"
✅ 这是目前在 Linux 上让容器访问宿主机服务的推荐方式。
🌐 四、host-gateway
的工作原理
- Docker 启动时会创建一个虚拟网桥(默认
docker0
),其 IP 通常是172.17.0.1
。 - 所有使用默认桥接网络的容器都会连接到这个网桥,IP 为
172.17.x.x
。 - 宿主机本身作为这个网络的“网关”,可以被容器通过
172.17.0.1
访问。 host-gateway
就是 Docker 自动解析为这个网关 IP 的机制。
你可以通过以下命令查看:
# 查看 docker0 网桥 IP
ip addr show docker0
# 或查看 bridge 网络的网关
docker network inspect bridge | grep Gateway
输出示例:
"Gateway": "172.17.0.1"
🆚 五、host-gateway
vs 手动 IP vs --network=host
方式 | 命令示例 | 优点 | 缺点 |
---|---|---|---|
host-gateway |
--add-host=host.docker.internal:host-gateway |
跨平台、自动解析、无需硬编码 IP | 需 Docker 20.10+ |
手动 IP | --add-host=host.docker.internal:172.17.0.1 |
兼容老版本 Docker | IP 可能变化,不灵活 |
--network=host |
docker run --network=host ... |
容器共享宿主机网络,直接访问 localhost |
安全性低,端口冲突风险高,不适用于 Docker Desktop(macOS) |
✅ 推荐使用
host-gateway
:安全、灵活、可移植。
⚠️ 六、注意事项
-
Docker 版本要求:
host-gateway
需要 Docker Engine 20.10 或更高版本。- 旧版本会报错:
invalid IP address "host-gateway"
。
-
宿主机服务必须监听正确地址:
- 服务不能只监听
127.0.0.1
,必须监听0.0.0.0
或172.17.0.1
。 - 错误示例:
app.listen(3000, '127.0.0.1')
→ 容器无法访问。 - 正确示例:
app.listen(3000, '0.0.0.0')
- 服务不能只监听
-
防火墙/安全组:
- 确保宿主机防火墙允许来自
172.17.0.0/16
网段的连接。
- 确保宿主机防火墙允许来自
-
Docker Desktop 已内置支持:
- 在 Windows/macOS 的 Docker Desktop 中,
host.docker.internal
默认可用(无需host-gateway
),但显式添加更可靠。
- 在 Windows/macOS 的 Docker Desktop 中,
🧪 七、验证 host-gateway
是否生效
# 启动一个测试容器
docker run --rm --add-host=host.docker.internal:host-gateway \
alpine ping host.docker.internal
或进入容器查看 hosts:
docker run -it --add-host=host.docker.internal:host-gateway alpine
/ # cat /etc/hosts
输出应包含:
172.17.0.1 host.docker.internal
📌 八、总结
项目 | 说明 |
---|---|
名称 | host-gateway |
类型 | Docker 保留关键字 |
用途 | 让容器访问宿主机服务 |
典型用法 | --add-host=host.docker.internal:host-gateway |
适用场景 | 开发调试、访问宿主机数据库/API、CI/CD |
最低版本 | Docker 20.10 |
推荐指数 | ⭐⭐⭐⭐⭐ |
💡 一句话总结:
host-gateway
是 Docker 提供的“魔法变量”,自动指向宿主机在 Docker 网络中的网关 IP,是容器安全访问宿主机服务的最佳实践。