Docker Container – Accessing Localhost Service

dockeriptableslinuxnetworking

I have a service bound to a localhost which I would like to be able to access from inside a Docker container. Relevant netstat output: (The service is on port 1143)

$ netstat -tulpn
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program nam
tcp        0      0 127.0.0.1:1143          0.0.0.0:*               LISTEN      23317/protonmail-br
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1527/sshd

Since Docker for linux currently has no clean way to obtain the IP of the host, I am using the qoomon/docker-host workaround image which exposes the host over a bridge network. I can access the host from my container using dockerhost:

bash-5.0# ping dockerhost
PING dockerhost (172.22.0.2): 56 data bytes
64 bytes from 172.22.0.2: seq=0 ttl=64 time=0.187 ms
64 bytes from 172.22.0.2: seq=1 ttl=64 time=0.298 ms
64 bytes from 172.22.0.2: seq=2 ttl=64 time=0.126 ms

I am using telnet to see if the container can connect to the port.

Services bound to 0.0.0.0 are accessible:

bash-5.0# telnet dockerhost 22
SSH-2.0-OpenSSH_7.6p1 Ubuntu-4ubuntu0.3

However, the service bound only to localhost is not:

bash-5.0# telnet dockerhost 1025
telnet: can't connect to remote host (172.22.0.2): Connection refused

How can I access this service from within the container, without exposing the service to the outside world?

Best Answer

Since Docker for linux currently has no clean way to obtain the IP of the host...

The clean way to get an IP address for your host is to use the address of the default gateway visible inside your container. This is the address of the bridge interface on the host to which your container is connected. Any service on your host listening on all interfaces will be accessible at this address.

However, the service bound only to localhost is not...

That's entirely expected: a service listening on the localhost address can be accessed only from the local host. It cannot be accessed from another host on a locally attached network (which is effectively what your container is from a networking perspective).

If you want to be able to access a host service from your container, you will need to either:

  • Have the service listen on all addresses (0.0.0.0),
  • Have the service listen explicitly on the appropriate docker bridge address, or
  • Have the service listen on some other address and pass that address into the container as an environment variable or via some other configuration mechanism