On ubuntu 18.04 with ufw enabled I run docker container which is supposed to connect a django app to a locally installed Postgresql server.
Everything runs perfect when ufw is disabled
docker-compose -f docker-compose.prod.yml run --rm app sh -c 'python manage.py createsuperuser'
But with enabled ufw I get the following error:
conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
django.db.utils.OperationalError: could not connect to server: Operation timed out
Is the server running on host "host.docker.internal" (172.17.0.1) and accepting
TCP/IP connections on port 5432?
I have following ufw rules
$ sudo ufw status
Status: active
To Action From
-- ------ ----
Nginx Full ALLOW Anywhere
OpenSSH ALLOW Anywhere
20/tcp ALLOW Anywhere
21/tcp ALLOW Anywhere
990/tcp ALLOW Anywhere
40000:50000/tcp ALLOW Anywhere
Nginx Full (v6) ALLOW Anywhere (v6)
OpenSSH (v6) ALLOW Anywhere (v6)
20/tcp (v6) ALLOW Anywhere (v6)
21/tcp (v6) ALLOW Anywhere (v6)
990/tcp (v6) ALLOW Anywhere (v6)
40000:50000/tcp (v6) ALLOW Anywhere (v6)
How to configure ufw properly and let the container connect to Postgres?
Your firewall is blocking the connection from docker container since it originates on another network.
To fix this you should enable access from that docker network to your Postgres instance (I assume its port 5432).
So, when you use docker-compose up, a specific docker network is created. You can look it up by using command:
docker network ls
When you locate your network use command docker inspect {network name}
to get additional information about it. The information you are looking for is the network's gateway. The portion of it should look something like this:
...
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
...
The ip you are looking for is in this example 172.18.0.1
.
So now you know from which interface your container is connecting to Postgres and you can enable it in your firewall. Since you don't want to open your firewall for everybody you can use something like this:
ufw allow in from 172.18.0.0/16
This will also allow the entire network to access and not just specific IPs. That is a useful option since containers can change IPs when restarted.