添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams From inside of a Docker container, how do I connect to the localhost of the machine? (43 answers)
Closed last year .

On Mac and Windows it is possible to use host.docker.internal (Docker 18.03+) inside container.

Is there one for Linux that will work out of the box without passing env variables or extracting it using various CLI commands?

There is open PR which add "host.docker.internal" feature to Linux. Wait until it will be accepted, and now as a workaround, you can use special container which add unified "dockerhost" host and you can use this from docker. Serhii Popov Jul 5, 2019 at 16:20 It should be noted that docker-for-windows is a specific product line and will not cover docker on windows in general. For example I use docker on windows, using docker-toolbox (OG) so that it has less conflicts with the rest of my setup and I don't need HyperV. There is an answer in this thread using grep, awk and netstat, which works for me; although generally, mixed network environments can also be solved with LAN or WAN level hostnames, than machine hostnames. This is then more explicit and flexible / composable than hacking at docker VM's MrMesees Oct 6, 2021 at 1:55 Wow! 172.17.0.1 actually works! I found this nowhere in the documentation or any of the forums complaining about host.docker.internal not working. Is this IP guaranteed to always link to the host machine? Jules Colle May 30, 2020 at 14:00 @JulesColle It is "guaranteed" as long as you are on the default network. 172.17.0.1 is no magic trick, but simply the gateway of the network bridge , which happens to be the host. All containers will be connected to bridge unless specified otherwise. See here FirefoxMetzger Mar 2, 2021 at 14:52 This DOES NOT work on all cases. If you have other networks, a new interface is going to be created: 172.17.0.1, 172.18.0.1, 172.19.0.1 and so on (try ifconfig to list all interfaces). You have to manually obtain the IP for your network. Federico Jun 29, 2021 at 17:48

For linux systems, you can – starting from major version 20.04 of the docker engine – now also communicate with the host via host.docker.internal . This won't work automatically , but you need to provide the following run flag:

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

See the answer here: https://stackoverflow.com/a/61424570/3757139

See also this answer below to add to a docker-compose file - https://stackoverflow.com/a/67158212/243392

Is there a way to enable this in daemon.json or something? I'm thinking about test environments of Rancher and Kubernetes, where I don't want to take care of every single one of the many containers. – qräbnö Nov 26, 2020 at 18:20 When running--add-host=host.docker.internal:host-gateway on CentOS I received the error invalid argument "host.docker.internal:host-gateway" for "--add-host" flag: invalid IP address in add-host: "host-gateway" Are you expecting to need to replace host-gateway with the actual host IP? – mummybot Dec 3, 2020 at 16:08 this works for me too. 172.17.0.1 is bridge network's gateway address in my case. if anyone has different network settings , they can get this by doing docker inspect. – Aniket Chopade Dec 8, 2020 at 13:52 Only newer docker versions have the magical string host-gateway, that converts to the docker default bridge network ip (or host's virtual IP when using docker desktop). You can test running: docker run --rm --add-host=host.docker.internal:host-gateway ubuntu:18.04 cat /etc/hosts, then see if it works and show the ip in the hosts file (there should be a line like 172.17.0.1 host.docker.internal in it). – Lucas Basquerotto Apr 20, 2021 at 19:47

If you are using Docker Compose + Linux, you have to add it manually (at least for now). Use extra_hosts on your docker-compose.yaml file:

version: '3.7'
services:
    build:
      context: .
    extra_hosts:
      - "host.docker.internal:host-gateway"

Do not forget to update Docker since this only works with Docker v20.10+.

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

if i want to access port 3000 on host, is this how i access it from container: http://host.docker.internal:3000/ ? – Javohir Mirzo Fazliddinov Aug 21, 2021 at 17:13

One solution is to use a special container which redirects traffic to the host. You can find such a container here: https://github.com/qoomon/docker-host. The idea is to grab the default route from within the container and install that as a NAT gateway for incoming connections.

An imaginary example usage:

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

This is my solution:

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

then in docker-compose:

extra_hosts:
  docker.host: ${IP_ADDRESS}
                On Linux/Debian docker with this cmd I get nothing. Better is: /sbin/ip route|awk '/default/ { print $3 }'
– GetoX
                Sep 28, 2020 at 8:57
                The above ip route example prints the gateway, not the docker0 io. The below should work:  # ip route | awk '/docker0/ {print $9}'
– Adam Shand
                Jan 3, 2022 at 9:12
                I use this solution combined with host.docker.internal flag in my case (Linux). Looks like host.docker.internal work fine in macOS
– Semooze
                Sep 21 at 12:14

For linux there isn't a default DNS name for the host machine. This can be verified by running the command:

docker run -it alpine cat /etc/hosts

This feature has been requested, however wasn't implemented. You can check this issue. As discussed you can use the following command to find the IP of the host from the container.

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

Alternatively, you can provide the host ip to the run command via docker run --add-host dockerHost:<ip-address> ...

That's not equivalent by any means. Having something that will resolve with dns gives you the ability to put it in config files without evaluating or sed'ing, or other funky stuff. – James O'Brien Apr 5, 2018 at 3:38 Well I would like to say thank you. This worked on my windows setup which uses docker-machine (I know OG). Normally I run a pass-through nginx so that I can talk to docker via a single container, but talking back to the host seems to be very OS / setup specific. It worked for me and I'm ecstatic for that. Thank you! – MrMesees Oct 6, 2021 at 1:24

Doing HTTP request towards the host:

  • Run the following command to get the static IP: ip addr show | grep "\binet\b.*\bdocker0\b" | awk '{print $2}' | cut -d '/' -f 1

  • Add the new IP to allowed hosts

  • Use the IP address just found in your requests: req = requests.get('http://172.17.0.1:8000/api/YOUR_ENDPOINT')

    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
    

    It will add host.docker.internal to your hosts. Then you can use it in xdebug config.

    Here is example of env variable in 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
    

    host.docker.internal exists only in Windows WSL because Docker Desktop for Windows runs Docker daemon inside the special WSL VM Docker-Desktop. It has its own localhost and its own WSL2 interface to communicate with Windows. This VM has no static IP. The IP is generated every time when VM is created and passed via host.docker.internal in the generated /etc/hosts to every distro. Although there is no bridge or real v-switch all ports opened on eth0 of VM internal network are mapped on the host Local network, BUT NOT ON THE ETH0 OF THE HOST. There is no real bridge and port mapping - nothing to configure. Inside WSL VM its Localhost is the same as the localhost of the Linux machine. 2 processes inside WSL VM can communicate via localhost. Cross-distro IPC must use host.docker.internal. It is possible to create bridge inside WSL VM -Docker does it.

    Another hint from the docs: This (using host.docker.internal) is for development purpose and does not work in a production environment outside of Docker Desktop. – Daniel W. Aug 10, 2022 at 17:56 This question is about connecting to the host system, not another service inside the same docker-compose environment. – burny May 7, 2021 at 12:30 Two things: a) it is the correct answer to the underlying problem (as opposed to hacking around DNS resolution using /etc/hosts) and b) using internals of docker to do the simple thing such accessing exposed ports is, and has always been, discouraged. That's what the -p or "expose" in docker-compose does. I understand the question is a bit different, but it stems from another mistake which by mocking around with /etc/hosts is just covered - not fixed. – Matthias Hryniszak Dec 8, 2021 at 9:48
  •