无法通过psycopg2连接到Postgres容器?

时间:2020-06-19 02:32:11

标签: postgresql docker networking docker-compose psycopg2

我有一个看起来像这样的docker-compose文件

version: "3.7"

services:
  app:
    stdin_open: true  
    tty: true 
    build:
      context: .
      dockerfile: app.Dockerfile
    volumes:
      - ${HOST_SAVE_DIRC}:${CONTAINER_SAVE_DIRC}
    depends_on:
      - postgres

  postgres:
    image: 'postgres'
    environment:
      - POSTGRES_DB=${POSTGRES_DB}
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_HOST_AUTH_METHOD=trust
    restart: always
    expose:
      - "5432"

其中POSTGRES_USER之类的变量是来自环境文件的条目。 app.Dockerfile看起来像

FROM python:3.8.3-slim-buster
COPY src /src/
COPY init.sql .
COPY .env .
COPY run.sh run.sh
COPY requirements.txt .
RUN ls -a
RUN pip install --no-cache-dir -r requirements.txt

创建容器,然后使用被调用程序的主要功能将用户登录到app容器-这是数据库调用时

我试图从app容器通过postgres连接到psycopg2容器。但是,当我尝试这样做时,会出现以下错误:

psycopg2.OperationalError: could not connect to server: No route to host
    Is the server running on host "postgres" (172.22.0.2) and accepting
    TCP/IP connections on port 5432?

使用看起来像这样的psycopg2通话

with psy.connect(host='postgres', port=5432, user='postgres', password='postgres') as conn:
    ...

此psycopg2调用的条目与分配给docker-compose文件的env文件匹配。

我的理解是Postgres默认使用端口5432。同样,当docker-compose创建两个容器时-它为这些容器名称DIR_default创建一个docker网络,其中DIR是docker-compose文件所在的目录的名称可以使用docker-compose文件中列出的名称(在这种情况下为“ postgres”和“ app”)进行访问。

在各种尝试中:

  • 我已经检查过,并且在正在创建的容器和正在执行该操作的用户之间数据库没有关闭。

  • 我尝试了各种小的更改,例如更改容器名称,postgres登录信息等。

  • 我尝试将Postgres容器名称与link: "postgres:postgres"明确链接。

  • 建议其他解决方案here

任何帮助将不胜感激!我没有理由要发生这么简单的事情,但我也在这里。


编辑:

在运行Postgres时从app容器中ping docker exec app ping postgres_container_name容器似乎正在工作。这是否表明Docker网络已正确设置并且问题出在我头上?


编辑2:

尝试清除所有映像和容器,然后重新启动Docker守护程序,然后再启动我的PC。两种情况都不变。

作为参考,ping命令看起来像

docker exec python-app ping name_given_to_postgres_container

返回各种看起来像

的语句
64 bytes from name_given_to_postgres_container.project_name_default (172.18.0.3): icmp_seq=1 ttl=64 time=0.090 ms

除非我没有记错,否则我相信这表明ping成功。


提供给docker-compose的顶级.env文件

HOST_SAVE_DIRC=~/python_projects/project_directory/directory_in_project
CONTAINER_SAVE_DIRC=/pdfs

POSTGRES_DB=project_name  # same as project_directory
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_PORT=5432

这也是Python应用程序的requirements.txt文件

certifi==2020.4.5.1
chardet==3.0.4
idna==2.9
psycopg2-binary==2.8.5
read-env==1.1.0
requests==2.23.0
urllib3==1.25.9

使用docker exec -it container_id bash进入Postgres容器并运行psql -U postgres似乎是成功的-即使删除了restart: always。我还可以看到在docker-compose文件中命名的数据库也已创建。我有信心说这个容器不会自发死亡。

但是,通过nc name_given_to_postgres_container 5432-5433用netcat击中Postgres容器上的5432端口会返回类似于psycopg2返回的错误

arxivist_postgres_1 [172.22.0.3] 5433 (?) : No route to host
arxivist_postgres_1 [172.22.0.3] 5432 (postgresql) : No route to host

curl也返回相同的错误。所以我想问题不在于Postgres容器,psycopg2或主机名,而是端口?


修改3:

作为修复此项目的最后尝试,发布了该帖子所引用的完整项目at this link。如果有人想下载该存储库并尝试通过./start.sh自己构建docker容器,那可能就是寻找解决方案所需要的!

1 个答案:

答案 0 :(得分:1)

我以为我在运行Fedora 32的机器上安装了Docker。但是,从this article开始,在Fedora 32上设置Docker需要一些我以前不知道的额外步骤。

专门针对此问题,本文中列出的命令可使用以下命令将Docker添加到本地网络防火墙上的Docker列入白名单中

sudo firewall-cmd --permanent --zone=FedoraWorkstation --add-masquerade

因此,我相信我的问题的根本原因仅仅是我的app容器被防火墙阻止访问postgres容器。进行上述更改使程序终于可以工作了!