ufw 禁止 docker 容器连接到 postgres

ufw forbids docker container to connect to postgres

在 ubuntu 18.04 上启用了 ufw 我 运行 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。