Troubleshooting Docker to Host communication

I’m setting up deployment of my application to a new server (running Debian) and I’m having a lot of trouble figuring out how to allow my Docker container to talk to the Postgres instance on the host.

On my dev server it works fine, but the new one is a little different and apparently that makes all the difference.

I have Postgres configured to accept connections from the 172.17.0.0/16 network and I am using the --addhost host.docker.internal:host-gateway approach to resolve the host url, but when my container tries to make a connection it times out. When I sign in to bash on one of my containers and try nc -w 5 -v -v -z host.docker.internal 5432 it also resolves the IP address for the host correctly but the request times out.

I think that my packets must be getting dropped between the container and the host - is that something Docker’s firewalling would do, and if so a) how would I confirm that and b) how can I allow it through?

Alternatively, given that my goal is allowing postgres traffic from my container, can I mount it as a socket? If so, how would I go about that in my docker-compose? I tried adding the socket as a volume and it gave me messages like: Error response from daemon: invalid mount config for type "volume": invalid mount path: 'not-even-the-postgres-volume' mount path must be absolute for other volumes. I think I ran into this before and it was a permissions problem, but I don’t remember how I resolved it!

The explanation might be way simpler. The source network 172.17.0.0./16 is only used, if the container is attached to the default bridge. Every user defined network will have a different cidr range.

1 Like

On Docker-CE host-gateway will resolve to the ip of the docker0 interface, which by default is 172.17.0.1. Unless your database listens on 172.17.0.1 as well, the above command can never succeed.

I was using the default bridge, looking at the documentation it seems like maybe I should be defining my own network but it was hard to find any good guidance on how to do that.

The database was listening for any connections from the 172.17.0.0/16 subnet, but even when I opened it up to just accept any incoming connections (not a scenario I want to use long-term but I needed to get it working) it never received any requests.

I have solved the problem for now by mounting the socket instead, but I would like to understand why the networking wasn’t working.

Do you mean Postgresql actually listened on the IP that @meyay shared or you just configured Postgresql to allow connections from that subnet? If the database server listens on localhost for example, even if it allows connections from another subnet, there will be no way for the container to find an IP address to access the database server.

The database was configured to listen to everything (just configured to ‘*’ in postgres.conf) and then I was leaning on the pg_hba.conf to limit what incoming connections it would accept, but none of the connection attempts were arriving at the database; my best guess is that Docker’s IPChains configuration was blocking the traffic, but I couldn’t see how to configure that.

Docker would not blockk it, but you can check if you have any firewall enabled on Debian. You can also test another command like this running on the host:

python3 -m http.server --bind 0.0.0.0 9999

And run a container with curl and access it like:

docker run --rm -it --add-host host.docker.internal:host-gateway nicolaka/netshoot

and

curl host.docker.internal:9999

If it doesn’t work, stay in the container and run:

ip a

and

cat /etc/hosts

So check the interfaces in the container and the IP of host.docker.internal in the hosts file.

Using the nicolaka/netshoot image you can run other network debug tools too.

1 Like

Thanks, this is really helpful!