连接到Docker容器(aiohttp)内的PostreSQL时,Connect调用失败

时间:2019-07-19 16:12:51

标签: python-3.x postgresql docker aiohttp

我有一个简单的REST API,它使用aiohttp,sqlalchemy和PostgreSQL。

我曾经在本地运行我的应用程序,并在docker容器中运行了PostgreSQL。我使用localhost:5432

连接到它

现在我正尝试将我的应用程序添加到docker-compose中,并且在从中连接到postgresql时遇到问题。

这是我的撰写文件:

version: "3"

services:

  db:
    image: postgres:9.4
    container_name: db
    restart: always
    ports:
      - "5432:5432"
    command:
      - "postgres"
      - "-c"
      - "listen_addresses=*"
    environment:
      POSTGRES_DB: library
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: pass

  innerio:
    container_name: innerio
    restart: 'on-failure'
    build: .
    volumes:
      - .:/innerio
    command: python3 api/models.py && python3 main.py
    ports:
      - "8080:8080"
    depends_on:
      - db

我的aiohttp运行部分:

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    app = loop.run_until_complete(main(loop))
    run_app(app, host='0.0.0.0', port=8080)

还有保存有关数据库信息的字符串:

DB_ADDRESS = 'postgresql://admin:pass@db:5432/library'

使用上述设置,我会收到此错误:

  

内在|引发OSError(err,f'Connect调用失败{address}')

     

内在| ConnectionRefusedError:[Errno 111]连接呼叫失败   ('172.22.0.2',5432)

我想念什么?

1 个答案:

答案 0 :(得分:0)

您的应用程序可能在postgres实际监听之前尝试连接数据库。您已经在撰写文件中设置了一个depends_on键,但是几乎没有任何作用:这意味着您的应用程序要等到您的postgres容器启动后才能启动,但是这与是否或不相关。实际上Postgres尚未准备好服务请求。

理想情况下,您应该编写应用程序,使其在遇到数据库连接失败时仍然健壮。这样不仅可以解决启动问题,还可以让您在应用程序处于活动状态时重新启动数据库容器。

最简单的解决方案(仅解决启动问题)是将数据库连接置于一个循环中,例如:

while True:
  try:
    connect_to_database()
    break
  except ConnectionRefusedError:
    log_error('database connection refused, retrying in 5 seconds...')
    time.sleep(5)