211

在 Mac 和 Windows 上,可以在容器内使用docker.for.mac.host.internal(replaces docker.for.mac.localhost) 和docker.for.win.host.internal(replaces docker.for.win.localhost) host.docker.internal (Docker 18.03+)。

有没有一种适用于 Linux 的工具,它可以在不传递环境变量或使用各种 CLI 命令提取它的情况下开箱即用?

4

11 回答 11

171

取决于你想要做什么。如果你正在运行--net=hostlocalhost应该可以正常工作。如果您使用默认网络,请使用静态 IP 172.17.0.1。我怀疑两者的行为都不会与那些域完全相同。

于 2018-01-31T16:37:10.717 回答
138

对于 linux 系统,您可以 - 从20.04docker 引擎的主要版本开始 - 现在还可以通过host.docker.internal. 这不会自动工作,但您需要提供以下运行标志:

--add-host=host.docker.internal:host-gateway

在此处查看答案:https ://stackoverflow.com/a/61424570/3757139

另请参阅下面的此答案以添加到 docker-compose 文件 - https://stackoverflow.com/a/67158212/243392

于 2020-06-17T14:17:50.033 回答
80

如果您使用Docker Compose+ Linux,则必须手动添加它(至少现在是这样)。extra_hosts在您的docker-compose.yaml文件上使用:

version: '3.7'

services:

  fpm:
    build:
      context: .
    extra_hosts:
      - "host.docker.internal:host-gateway"

文档 - https://docs.docker.com/compose/compose-file/compose-file-v3/#extra_hosts

不要忘记更新 Docker,因为这只适用于Docker v20.10+

来源:https ://github.com/docker/for-linux/issues/264#issuecomment-784985736

于 2021-04-19T08:09:54.233 回答
27

一种解决方案是使用将流量重定向到主机的特殊容器。你可以在这里找到这样的容器:https ://github.com/qoomon/docker-host 。这个想法是从容器中获取默认路由并将其安装为传入连接的 NAT 网关。

一个虚构的示例用法:

docker-host:
  image: qoomon/docker-host
  cap_add: [ 'NET_ADMIN', 'NET_RAW' ]
  restart: on-failure
  environment:
    - PORTS=999

some-service:
  image: ...
  environment:
    SERVER_URL: "http://docker-host:999"
  command: ...
  depends_on:
    - docker-host
于 2018-03-07T10:01:17.713 回答
19

这是我的解决方案:

IP_ADDRESS=$(ip addr show | grep "\binet\b.*\bdocker0\b" | awk '{print $2}' | cut -d '/' -f 1)

然后在 docker-compose 中:

extra_hosts:
  docker.host: ${IP_ADDRESS}
于 2020-04-02T21:09:10.710 回答
17

对于 linux,主机没有默认的 DNS 名称。这可以通过运行以下命令来验证:

docker run -it alpine cat /etc/hosts

已请求此功能,但未实施。你可以检查这个问题。如前所述,您可以使用以下命令从容器中查找主机的 IP。

netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}'

或者,您可以通过以下方式将主机 ip 提供给运行命令docker run --add-host dockerHost:<ip-address> ...

于 2018-01-31T16:52:17.327 回答
11

https://github.com/docker/for-linux/issues/264

IP=$(ip -4 route list match 0/0 | awk '{print $3}')
echo "Host ip is $IP"
echo "$IP   host.docker.internal" | sudo tee -a /etc/hosts

它将添加host.docker.internal到您的主机。然后你可以在 xdebug 配置中使用它。

这是 env 变量的示例docker-compose.yml

XDEBUG_CONFIG: remote_host=host.docker.internal remote_autostart=On remote_enable=On idekey=XDEBUG remote_log=/tmp/xdebug.log remote_port=9999
于 2020-05-16T04:13:07.770 回答
9

使用 docker0 接口 ip,比如 172.17.0.1,可能是一个很好的解决方法。

只要确保您需要访问的服务侦听外部连接即可。一个典型的例子是默认绑定到 127.0.0.1 的 Mysql,导致无法访问,直到您允许外部连接(例如绑定到 0.0.0.0)

于 2020-02-20T16:09:14.713 回答
4

host.docker.internal 仅存在于 Windows WSL 中,因为 Docker Desktop for Windows 在特殊的 WSL VM Docker-Desktop 中运行 Docker 守护程序。它有自己的 localhost 和自己的 WSL2 接口来与 Windows 通信。此 VM 没有静态 IP。每次创建 VM 时都会生成 IP,并通过生成的 /etc/hosts 中的 host.docker.internal 将其传递给每个发行版。尽管没有桥接器或真正的 v-switch,但在 VM 内部网络的 eth0 上打开的所有端口都映射到主机本地网络,但不在主机的 ETH0 上。没有真正的网桥和端口映射 - 无需配置。在 WSL VM 内部,它的 localhost 与 Linux 机器的 localhost 相同。WSL VM 中的 2 个进程可以通过 localhost 进行通信。跨发行版 IPC 必须使用 host.docker.internal。可以在 WSL VM 中创建桥接器 - Docker 可以做到。

于 2020-11-01T10:19:41.993 回答
4

tldr; 通过静态IP访问主机172.17.0.1

向主机发出 HTTP 请求:

  1. 运行以下命令以获取静态 IP:ip addr show | grep "\binet\b.*\bdocker0\b" | awk '{print $2}' | cut -d '/' -f 1

  2. 将新 IP 添加到允许的主机

  3. 使用刚刚在您的请求中找到的 IP 地址:req = requests.get('http://172.17.0.1:8000/api/YOUR_ENDPOINT')

于 2021-01-01T06:39:29.270 回答
0

对于 linux,我可以使用我尝试连接的服务名称,例如,我的一个容器 (php-fpm) 正在尝试连接 mysql,所以我使用mysql它作为主机名,因为这是我的服务名称码头工人撰写

于 2020-09-15T21:57:56.770 回答