ufw禁止docker容器连接到postgres

问题描述

在启用了ufw的ubuntu 18.04上,我运行docker容器,该容器应该将Django应用程序连接到本地安装的Postgresql服务器。

禁用 ufw 时,一切运行正常

docker-compose -f docker-compose.prod.yml run --rm app  sh -c 'python manage.py createsuperuser'

但是启用了ufw时,出现以下错误

 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?

我遵守ufw规则

$ 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)  

如何正确配置ufw,并使容器连接到Postgres?

解决方法

您的防火墙正在阻止来自Docker容器的连接,因为它起源于另一个网络。

要解决此问题,您应该启用从该docker网络访问您的Postgres实例(我假定其端口为5432)。

因此,当您使用docker-compose up时,会创建一个特定的docker网络。您可以使用以下命令进行查找:

docker network ls

找到网络后,使用命令docker inspect {network name}获取有关它的其他信息。您正在寻找的信息是网络的网关。它的一部分应该看起来像这样:

...
"IPAM": {
            "Driver": "default","Options": {},"Config": [
                {
                    "Subnet": "172.18.0.0/16","Gateway": "172.18.0.1"
                }
            ]
        },...

在此示例中,您要查找的IP是172.18.0.1

因此,现在您知道容器从哪个接口连接到Postgres,并且可以在防火墙中启用它。由于您不想为所有人打开防火墙,因此可以使用以下方式:

ufw allow in from 172.18.0.0/16

这也将允许整个网络访问,而不仅仅是特定IP。这是一个有用的选项,因为容器在重新启动时可以更改IP。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...