0

I have service that is running at port 127.0.0.1:5433 in linux host machine, I want to access this service from the container using host.docker.internal but i could not.

version: "3"
services:
  streamlit:
    image: xxx/xxx
    build:
      context: .
      dockerfile: Dockerfile
      target: final
    ports:
      - "8501:8501"
    env_file:
      - .env
    entrypoint: scripts/app_entrypoint.sh
    volumes:
      - .:/app
    extra_hosts:
      - "host.docker.internal:host-gateway"

enter image description here

here is the output of ss -ltn which shows that 127.0.0.1:5433 is LISTENING, but when i try to access this port from inside the container, It says that port is closed. I doubt that this might be issues related to 127.0.0.1 and 0.0.0.0 so i started python http server on port 5433 and bind 0.0.0.0 then i was able to access it from inside the container, but when i start python http server and bind 127.0.0.1 instead i could not access from inside the container.

But i want to access service running on 127.0.0.1 from the container. My collegue on MAC is able to do so but I am using Linux machine and having this issue.

as you can see i have also used extra_hosts in my docker compose file as per documentation.

    extra_hosts:
      - "host.docker.internal:host-gateway"

Isn't this sufficient to access service running on 127.0.0.1? and not only 0.0.0.0

Aayush Neupane
  • 1,066
  • 1
  • 12
  • 29
  • You cannot use localhost in docker. Check this https://stackoverflow.com/a/71879028/3957754 – JRichardsz Jul 12 '23 at 05:39
  • What exactly you are trying to do? Accessing the port `5433` from the container itself, or accessing `5433` from another container? – PRATHEESH PC Jul 12 '23 at 05:40
  • `access this port from inside the container` ? , Can you please clarify more ? – George Jul 12 '23 at 07:16
  • I want to do somethink like this, which i am not able to, https://docs.docker.com/desktop/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host For service running on `127.0.0.1:5433`of my host machine using `host.docker.internal`, I have replaced dbhost by `host.docker.internal` and service is listening on `127.0.0.1:5433`. i have added `extra_hosts` configuration but still cannot access port 5433 in my host from the container @George – Aayush Neupane Jul 12 '23 at 07:48
  • hmmm, can you show how you update the dbhost ? as much as I know, `host.docker.internal` is only available to Docker Desktop for mac and windows. and why even bother with adding a hostname when you can easily use the IP instant? – George Jul 12 '23 at 08:11
  • I want to make it work on all platform because others developers use mac and windows. – Aayush Neupane Jul 12 '23 at 08:23
  • if i start python server on 0.0.0.0:8000 i can access from the container, but if i start the python server on 127.0.0.1:8000 i cannot access, but when i looked for answer i find answer saying we can access something running on 127.0.0.1 using host.docker.internal – Aayush Neupane Jul 12 '23 at 08:24

3 Answers3

0

I am not pretty sure, But I guess you've misunderstood 0.0.0.0 and 127.0.0.1 so here is a small clarification.

127.0.0.1 is a special IP address that is used to refer to the loopback network interface of the local machine, it will only accept connections from processes running on the same machine.

while on the other hand, 0.0.0.0 is used to refer to all available network interfaces on the local machine. When you run a server process on your local machine and bind it to 0.0.0.0, it will accept connections from any IP address.

and here is what you have done wrong, if you type in your terminal docker network inspect bridge you can check what is the IP that docker network is using. And I Think and am not sure that its 172.17.0.0/16 by default.

You can check you container IP with this command, and you can access it throw the external port docker inspect --format '{{ .NetworkSettings.Networks.bridge.IPAddress }}' my-container

if you want to communicate with the container from another container , you can use {container_name}:{internal_port} as from your example this will be streamlit:8501

George
  • 2,292
  • 2
  • 10
  • 21
0

On native Linux without Docker Desktop, the host service will be unreachable without reconfiguring it somehow.

When a Unix server starts up, it calls bind(2) in some form to set up its network listener. It is passed one of the host's IP addresses, and binds to the specific corresponding network interface; or it is passed 0.0.0.0 and binds to all interfaces.

If you run ifconfig(8) you'll probably see at least three network interfaces. eth0 or wl0 or something else will be your primary external interface; lo0 is the loopback interface; and docker0 will correspond to the the default Docker network. If you have additional Docker networks (like the Compose default network) those will each have an additional network interface.

Now, here's the trick, on native Linux, without Docker Desktop: a call to host.docker.internal will in fact reach the host, but it will come from the dockerN interface that matches the Compose file's Docker network. Your host process bound to 127.0.0.1 is only listening on the lo0 interface, so it can't accept the connection.

There isn't an easy generic answer to this. That port number suggests a secondary PostgreSQL database, and moving that into a container could help simplify the deployment. If you know the Docker network interface address then you can configure the host server to listen on it too, but this can change as networks are destroyed and recreated. You might be able to use iptables(8) to allow the server to listen on all addresses but have the host firewall refuse connections from outside. None of these are things you can change in the Docker setup (beyond adding the container) and if you are a programmer and not a system administrator they may be out of your control.

David Maze
  • 130,717
  • 29
  • 175
  • 215
-1

Setting extra_hosts as host.docker.internal:host-gateway does not enable access to the host computer's 127.0.0.1 (localhost) from within the Docker container.

When you set extra_hosts as host.docker.internal:host-gateway, it enables the container to access the host's network gateway. This allows the container to communicate with other devices on the local network or the internet. However, it does not grant access to the loopback address 127.0.0.1 on the host.

The loopback address 127.0.0.1 is specific to each network namespace, and the container has its own separate network namespace from the host. Consequently, the container's loopback address is distinct from the host's loopback address. Therefore, setting extra_hosts does not provide direct access to the host's 127.0.0.1.

If you need to access services running on the host's 127.0.0.1, you would typically use port mapping when running the container. By mapping the host's port to a specific port on the container, you can access the services running on the host. For example:

docker run -p 8080:8080 my-container

With this configuration, you can access the service running on 127.0.0.1:8080 on the host by using localhost:8080 within the container.

To further understand more about loopback address, check out the following:

T-rex
  • 1
  • 1
  • I want to do somethink like this, which i am not able to, https://docs.docker.com/desktop/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host For service running on 127.0.0.1:8000 – Aayush Neupane Jul 12 '23 at 07:45
  • In the docs they are able to connect to service running on 8000 from the container, and clearly they are not using port mapping – Aayush Neupane Jul 12 '23 at 07:52