What is linux equivalent of "host.docker.internal"

216,122

Solution 1

Depends what you're trying to do. If you're running with --net=host, localhost should work fine. If you're using default networking, use the static IP 172.17.0.1. I suspect neither will behave quite the same as those domains.

Solution 2

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

Solution 3

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:

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

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

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

Solution 4

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

Solution 5

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}
Share:
216,122

Related videos on Youtube

klor
Author by

klor

Updated on February 13, 2022

Comments

  • klor
    klor about 2 years

    On Mac and Windows it is possible to use docker.for.mac.host.internal (replaces docker.for.mac.localhost) and docker.for.win.host.internal (replaces docker.for.win.localhost) 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?

    • James O'Brien
      James O'Brien about 6 years
      In 18.03 there is a docker.host.internal, but it didn't work for me.
    • Serhii Popov
      Serhii Popov almost 5 years
      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.
    • MrMesees
      MrMesees over 2 years
      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
  • James O'Brien
    James O'Brien about 6 years
    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.
  • cviejo
    cviejo almost 5 years
    More often than not grep | awk can be just awk: awk '/^0\.0\.0\.0/{print $2}' :)
  • Jules Colle
    Jules Colle almost 4 years
    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?
  • PHZ.fi-Pharazon
    PHZ.fi-Pharazon almost 4 years
    You can edit your /etc/hosts and add 172.17.0.1 docker.host.internal
  • Dan Burton
    Dan Burton almost 4 years
    On my Ubuntu VM, this is 172.17.0.1, which matches the above answer.
  • Alex
    Alex over 3 years
    I can attest the 172.17.0.1-trick this works with GitHub Actions!
  • GetoX
    GetoX over 3 years
    On Linux/Debian docker with this cmd I get nothing. Better is: /sbin/ip route|awk '/default/ { print $3 }'
  • qräbnö
    qräbnö over 3 years
    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.
  • user139442
    user139442 over 3 years
    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?
  • user139442
    user139442 over 3 years
    The magical IP number worked: `--add-host=host.docker.internal:172.17.0.1 `
  • Aniket Chopade
    Aniket Chopade over 3 years
    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.
  • Gherman
    Gherman over 3 years
    I disagree that it "depends what you're trying to do". It does not depend what we are trying to do. We are trying to do only one thing that is connect to the host machine from inside the container. I already know it is discouraged and that's why we can't. But I have a task to solve. PHP-code needs to connect from inside Docker to my code editor.
  • FirefoxMetzger
    FirefoxMetzger about 3 years
    @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
  • Lucas Basquerotto
    Lucas Basquerotto about 3 years
    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).
  • burny
    burny about 3 years
    This question is about connecting to the host system, not another service inside the same docker-compose environment.
  • Federico
    Federico almost 3 years
    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.
  • funder7
    funder7 almost 3 years
    awesome! finally I can use xdebug on linux too :-)
  • jawira
    jawira almost 3 years
    @funder7 lol, yes, I did this in order to use xdebug :)
  • Javohir Mirzo Fazliddinov
    Javohir Mirzo Fazliddinov over 2 years
    if i want to access port 3000 on host, is this how i access it from container: http://host.docker.internal:3000/ ?
  • Johannes Buchholz
    Johannes Buchholz over 2 years
    Doing this the added host entry seems to be in the wrong subnet
  • MrMesees
    MrMesees over 2 years
    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!
  • Matthias Hryniszak
    Matthias Hryniszak over 2 years
    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.
  • Adam Shand
    Adam Shand over 2 years
    The above ip route example prints the gateway, not the docker0 io. The below should work: # ip route | awk '/docker0/ {print $9}'
  • Felipe Valdes
    Felipe Valdes about 2 years
    actually, host.docker.internal works on OSX if using docker desktop as well