postgresql 无法从其他Docker容器中的Python应用程序连接到Docker容器中运行的Postgres数据库

3duebb1j  于 2023-03-17  发布在  PostgreSQL
关注(0)|答案(2)|浏览(151)

我有一个Postgres数据库在Docker容器中运行,一个Python应用程序在另一个Docker容器中运行。当我尝试使用SQLAlchemy从Python应用程序连接到Postgres数据库时,我收到以下错误:
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not connect to server: Connection refused Is the server running on host "localhost" (127.0.0.1) and accepting TCP/IP connections on port 5432?
我已经检查了Postgres容器是否正在运行,并且我可以使用DBeaver从我的主机连接到它,但是,当我尝试从Python应用程序容器连接时,我得到了上面的错误。
这是在docker compose中设置的Postgres

version: "3.7"
services:
  postgresql_database:
    container_name: postgresql_database
    image: postgres:13.8
    environment:
      POSTGRES_HOST: localhost
      POSTGRES_PASSWORD: MyPassword
      POSTGRES_USER: MyUsername
      POSTGRES_DB: "MyDatabase"
    volumes:
      - source: ../configs/postgresql
        target: /docker-entrypoint-initdb.d/
        type: bind
    networks:
      - default
      - app_network
    healthcheck:
      test:
        [
          "CMD",
          "pg_isready",
          "-q",
          "-U",
          "MyUsername",
          "-d",
          "MyDatabase"
        ]
      interval: 5s
      timeout: 1s
      retries: 2
    restart: unless-stopped

../configs/postgresql目录包含所有数据库sql脚本

这是python的设置

version: "3.7"
services:
  flask_app:
    image: https://not_allowed_to_share/flask_app:latest
    container_name: flask_app
    volumes:
      - source: ../configs/flask_app/config.yaml
        target: /config/config.yaml
        type: bind
    environment:
      CONTENT_CONNECTIONSTRING: DRIVER={PostgreSQL Unicode};SERVER=localhost;Port=5432;UID=MyUsername;PWD=MyPassword;Connect Timeout=5;DATABASE=MyDatabase;
      CONTENT_DBTYPE: postgresql_odbc
    networks:
      - app_network
    depends_on:
      - "postgresql_database"

    restart: "no"

../configs/flask_app/config.yaml包含连接字符串、调试模式等配置

这是连接字符串DRIVER={PostgreSQL Unicode};SERVER=localhost;Port=5432;UID=MyUsername;PWD=MyPassword;Connect Timeout=5;DATABASE=MyDatabase;
我也试过用Postgres服务的名称替换“localhost”,但仍然得到同样的错误。
如何修复此问题并从Docker容器中运行的Python应用程序连接到Postgres数据库?

axzmvihb

axzmvihb1#

你的python容器的“localhost”和postgres容器的“localhost”不一样。
解决此问题的方法:

  • 我不太记得DNS在Docker网络中是如何工作的,但是可以在python容器的连接字符串中使用主机名“postgresql_database
  • 或者,你可以定义固定的ip地址并在连接字符串中使用它们。参见网络
  • 使用SSH隧道为postgres端口建立隧道(这是权宜之计)
2wnc66cl

2wnc66cl2#

当您启动两个Docker合成部署时,这两个部署都将具有不同的网络,即使您在每个部署中将其命名为app_network(如示例中所示)。
启动两个部署,然后使用docker network list检查网络。您应该看到两个不同的网络。
我建议把这两个服务放在同一个docker-compose.yml中,因为数据库和应用程序是属于一起的,这样可以一起启动它们,并且它们将在同一个网络上。
flask_app服务中,您可以设置数据库服务的名称,而不是localhostlocalhost将是flask_app Docker容器本身,但数据库在不同的容器中运行。
所以在CONTENT_CONNECTIONSTRING中,您应该使用主机名postgresql_database而不是localhost
如果你真的想使用两个不同的Docker合成文件,你需要将网络标记为external。这样它就不会创建两个不同的网络,而是使用一个现有的网络。
1.使用docker network create app_network创建网络。
1.然后,在两个Docker合成文件中,按照您已经完成的操作设置网络:

services:
    [service_name]:
       networks:
         - app_network

1.在Docker合成文件的末尾,将app_network定义为外部网络:

networks:
  app_network:
    external: true
    name: app_network

相关问题