## 🐳 [[Docker]] 网络合并太麻烦?想“应急”通过主机端口通信?{#sec-f27028c85270} 通常情况下,容器之间通信的最佳实践是创建一个公共桥接网络,并通过服务名(例如:`http://app-b:8080`)进行调用。但现实中,总会遇到一些“特殊情况”,让你无法按部就班。 ## 遇到这些“无奈情况”时,不妨试试这个方法 {#sec-3da904d03848} * **与直接安装在主机上的服务通信时:** 当DB或Redis等服务直接安装在主机操作系统而非容器中,无法合并网络时。 * **不敢轻易改动他人容器的网络设置时:** 当你担心将自己的容器强行加入到他人复杂的网络设置中会导致故障时。 * **本地开发时只想“临时”验证连接:** 当你顾不上网络设计,只想立即确认请求是否能通过主机端口访问到服务时。 在这种情况下,`host.docker.internal` 就是一个非常有用的“作弊码”。 ![使用主机进行容器间通信](/media/whitedec/blog_img/4e661ed1ddb648529e5b1681c022cd25.webp) --- ## 解决方案:“窥探容器外部世界的窗口” `host.docker.internal` {#sec-979a012d89c8} 在容器内部调用 `127.0.0.1` 只能看到容器本身。此时,使用 `host.docker.internal` 这个特殊域名,可以穿透容器壁垒,找到主机的IP地址。 **Python (DRF) 代码示例:** ```python # 使用 'host.docker.internal' 代替 'localhost' 来访问主机端口。 # 如果 App-B 绑定在主机的 8080 端口,则按如下方式调用: NEXTCLOUD_URL = "http://host.docker.internal:8080" response = requests.get(NEXTCLOUD_URL) ``` --- ## ⚠️ [[Linux]] 用户请注意:需要“手动配置”{#sec-169e1a1f873c} `Docker Desktop` (适用于 Mac/Windows) 默认支持此功能,但对于**纯 `Linux` 服务器**,`Docker` 不会自动解析此域名。你需要在构建或运行时明确声明“此域名代表主机IP”。 **Docker Compose 配置示例:** ```yaml services: drf-app: image: my-drf-app-image extra_hosts: # 声明 host.docker.internal 这个名称将访问主机网关 - "host.docker.internal:host-gateway" ``` --- ## 这并非总是最佳选择 {#sec-bb28e4a13c7f} 再次强调,这种方法更像是**最后的手段**。 1. **最佳实践:** 创建公共桥接网络,并通过容器名称进行通信(安全性最高)。 2. **使用此方法的原因:** 当你需要访问直接在主机上运行的进程,或者在无法合并网络结构的“隔离”环境中时。 去年我记录的这个“紧急出口”用法,只应在常规方法受阻时,作为你的“秘密武器”来使用!