我有一个简单的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)
我想念什么?
答案 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)