简体   繁体   English

Flask 无法将 postgresql 与 docker-compose 连接

[英]flask can not connect postgresql with docker-compose

I use docker-compose built a flask app with postgresql.我使用 docker-compose 用 postgresql 构建了一个烧瓶应用程序。 But flask can not connect postgresql.但是flask无法连接postgresql。 Error message:错误信息:

     conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not connect to server: Connection refused
    Is the server running on host "postgres-db" (192.168.16.2) and accepting
    TCP/IP connections on port 5432?

When I go inside the docker container, and ping postgres-db , it works well.当我进入 docker 容器并 ping postgres-db ,它运行良好。 And I start the flask app, it works well too.我启动了烧瓶应用程序,它也运行良好。 It only can not connect when I use docker-compose up仅当我使用 docker-compose up 时无法连接

my docker-compose file:我的 docker-compose 文件:

version: '3.7'

services:
  postgres-db:
    restart: always
    image: postgres:11.1-alpine   
    privileged: true  
    ports:
      - 5432:5432  
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: Aa123456 
      PGDATA: /var/lib/postgresql/data/pgdata 
    volumes:
      - ./db/postgres/data:/var/lib/postgresql/data/pgdata

  api:
    build:
      context: ./api
      dockerfile: Dockerfile
    volumes:
      - './api:/usr/src/app'
    ports:
      - 5002:5000
    environment:
      - FLASK_CONFIG=development
      - FLASK_ENV=development
      - APP_SETTINGS=project.config.DevelopmentConfig
      - DATABASE_URL=postgres://postgres:Aa123456@postgres-db:5432/cms
      - DATABASE_TEST_URL=postgres://postgres:Aa123456@postgres-db:5432/cms_test
      - SECRET_KEY=ZQbn05PDeA7v11
    depends_on:
      - postgres-db
    container_name: api
    links: 
      - postgres-db:postgres-db

  nginx:
    build:
      context: ./nginx
      dockerfile: Dockerfile
    restart: unless-stopped
    ports:
      - 8080:8080
    depends_on:
      - api
      - client

  client:
    build:
      context: ./client
      dockerfile: Dockerfile
    volumes:
      - './client:/usr/src/app'
      - '/usr/src/app/node_modules'
    ports:
      - 3008:3000
    environment:
      - NODE_ENV=development
      - REACT_APP_SERVICE_URL=http://localhost:8080
      - CHOKIDAR_USEPOLLING=true
    depends_on:
      - api

You are experiencing a race condition: the application is trying to connect to the database before the database is available.您遇到了争用情况:应用程序试图在数据库可用之前连接到数据库。 This isn't a problem that's unique to Docker;这不是 Docker 独有的问题; if your application depends on an external resource (like a database server), then you need to write your code to handle situations like this.如果您的应用程序依赖于外部资源(如数据库服务器),那么您需要编写代码来处理此类情况。

A simple solution is to block the startup of your application until the database is available.一个简单的解决方案是在数据库可用之前阻止应用程序的启动。 Running something like SELECT 1 in a loop and waiting for that to succeed is sufficient.在循环中运行诸如SELECT 1类的东西并等待它成功就足够了。 An example shell script that does this would look something like this:执行此操作的示例 shell 脚本如下所示:

while ! psql -h postgresb-db -c 'select 1'; do
  sleep 1
done

If you're using sqlachemy in your flask application, you could do something similar:如果您在烧瓶应用程序中使用 sqlachemy,您可以执行类似的操作:

from sqlalchemy import create_engine
from sqlalchemy import exc
import time


while 1:
    try:
        e = create_engine('postgres://lars@localhost/sandbox')
        e.execute('select 1')
    except exc.OperationalError:
        print('Waiting for database...')
        time.sleep(1)
    else:
        break

print('Connected!')

The above works fine in terms of solving the startup race condition, but it doesn't handle the situation in which the database server restarts while your application is running.以上在解决启动竞争条件方面工作正常,但它不能处理在应用程序运行时数据库服务器重新启动的情况。 In this case, you need to gracefully handle disconnects/reconnects.在这种情况下,您需要优雅地处理断开/重新连接。 This requires a little more work in terms of the design of your code and is beyond the scope of this answer.这需要在代码设计方面做更多工作,并且超出了本答案的范围。 See this answer for some discussions around this topic.有关此主题的一些讨论,请参阅此答案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM