在Mac和Windows上,可以在容器内使用host.docker.internal (Docker 18.03+)。
host.docker.internal
Linux上是否有一种不需要传递env变量或使用各种CLI命令提取它就能开箱即用的方法?
这取决于你想做什么。如果你使用--net=host运行,localhost应该可以正常工作。如果您正在使用默认网络,请使用静态IP 172.17.0.1。我怀疑这两个领域的表现都不会与那些领域完全相同。
--net=host
localhost
172.17.0.1
对于linux,主机没有缺省的DNS名称。可以通过以下命令进行验证:
docker run -it alpine cat /etc/hosts
此功能已被请求,但尚未实现。你可以检查这个问题。如前所述,您可以使用以下命令从容器中查找主机的IP。
netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}'
或者,你可以通过docker run --add-host dockerHost:<ip-address> ...为run命令提供主机ip
docker run --add-host dockerHost:<ip-address> ...
一种解决方案是使用特殊的容器将流量重定向到主机。你可以在这里找到这样一个容器: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
使用docker0接口ip(比如172.17.0.1)可能是一个很好的解决方案。
只要确保您需要访问的服务侦听外部连接即可。一个典型的例子是Mysql,默认绑定到127.0.0.1,导致无法访问,直到你允许外部连接。绑定到0.0.0.0)
这是我的解决方案:
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}
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配置中使用它。
下面是docker-compose.yml中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
对于linux系统,你可以——从docker引擎的主版本20.04开始——现在也可以通过host.docker.internal与主机通信。这将不能工作自动,但你需要提供以下运行标志:
20.04
--add-host=host.docker.internal:host-gateway
在这里看到答案:https://stackoverflow.com/a/61424570/3757139
另请参阅下面的答案,以添加到docker-compose文件- https://stackoverflow.com/a/67158212/243392
对于linux,我可以使用我试图连接到的服务名,例如,我的一个容器(php-fpm)试图连接到mysql,所以我使用mysql作为主机名,因为这是我的docker-compose中的服务名
mysql
host.docker.internal只存在于Windows WSL中,因为Windows的Docker Desktop在特殊的WSL虚拟机Docker-Desktop中运行Docker守护进程。它有自己的本地主机和自己的WSL2接口来与Windows通信。虚拟机没有静态IP。每次创建VM时都会生成IP,并通过生成的/etc/hosts中的host.docker.internal传递到每个发行版。虽然没有网桥或真正的v-switch,但虚拟机内部网络eth0上开放的所有端口都映射在主机的本地网络上,而不是主机的eth0上。 没有真正的桥接和端口映射—不需要配置。 在WSL VM内部,它的Localhost与Linux机器的Localhost相同。WSL VM内部的2个进程可以通过localhost进行通信。跨发行版IPC必须使用host.docker.internal。可以在WSL VM内部创建桥接-Docker可以做到
tldr;通过静态IP 172.17.0.1访问主机
对主机进行HTTP请求:
执行以下命令获取静态IP
添加新的IP到允许的主机
使用在您的请求中找到的IP地址:req = requests.get('http://172.17.0.1:8000/api/YOUR_ENDPOINT')
req = requests.get('http://172.17.0.1:8000/api/YOUR_ENDPOINT')
如果你正在使用Docker Compose + Linux,你必须手动添加它(至少现在)。在你的docker-compose.yaml文件上使用extra_hosts:
Docker Compose
Linux
docker-compose.yaml
extra_hosts
version: '3.7' services: fpm: build: context: . extra_hosts: - "host.docker.internal:host-gateway"
不要忘记更新Docker,因为这只适用于码头工人v20.10 +。
来源:https://github.com/docker/for-linux/issues/264#issuecomment-784985736