开发者

容器无法访问 Mac 上的 localhost

每个容器都有自己的网络栈。在容器里,localhost 就是容器本身,而不是 Mac。

适用于:当前 macOS 版本上的 Docker Desktop 和 OrbStack。核查日期:2026年10月29日

症状

  • 容器中的 App 访问 localhost:5432 或类似端口时出现“connection refused”。
  • 同一个 URL 在 Mac 上的 Safari 浏览器或“终端”中都能正常访问。
  • 开发容器无法访问 Mac 上的模型服务器或 API。

可能的原因

  • localhost 指向容器。容器在自己的网络栈中查找该服务,而那里没有任何程序在监听。
  • 主机地址会变化。Docker 文档指出主机的 IP 地址会变化,因此提供了一个指向主机的特殊名称。
  • Mac 上的防火墙。macOS 防火墙或其他防火墙 App 可能会阻止发往该服务的传入连接。

如何检查

  1. 确认服务在 Mac 上能正常工作。将 8000 换成实际端口。

    curl http://localhost:8000
  2. 查看 Mac 上的服务监听的是哪个地址。

    lsof -nP -iTCP:8000 -sTCP:LISTEN

    输出 *:8000 表示所有地址,127.0.0.1:8000 表示仅限环回地址。

  3. 如果镜像中包含 wget,可在容器内测试该主机名。

    docker exec my-container wget -qO- http://host.docker.internal:8000

如何修复

  1. 在容器中,用 host.docker.internal 代替 localhost。Docker Desktop 和 OrbStack 都支持这个名称。

  2. 在 App 的配置中设置该地址,例如通过环境变量。

    docker run -e API_URL=http://host.docker.internal:8000 my-image
  3. 使用 OrbStack 时,也可以改用主机网络模式。这样在容器中通过 localhost 即可访问 Mac 上的服务。

    docker run --net host my-image
  4. 如果仍然无法连接,请检查 macOS 防火墙设置。参阅macOS 防火墙阻止传入连接。

使用 Kilobat

  1. Kilobat 的检查在 Mac 上运行,而不是在容器中。加上 --context container 可获得一条在容器中运行的命令。

    kilobat why http://localhost:8000 --context container
  2. 如果是托管服务要调用你的 Mac,使用 --context provider。Kilobat 会提示 localhost 是私有地址,该服务无法访问。

    kilobat why http://localhost:8000 --context provider

常见问题

host.docker.internal 在 Linux 上也能用吗?

本页只介绍 Mac。在 Docker Desktop for Mac 和 OrbStack 上,这个名称会解析为主机。

为什么 Safari 浏览器能访问该服务,容器却不能?

Safari 运行在 Mac 上,所以对它来说 localhost 就是 Mac。容器有自己的 localhost。

参考资料

参考资料核查于 2026年10月29日。man 手册页为 macOS 自带版本;在“终端”中用 man <name> 打开。