簡體   English   中英

Flask 無法將 postgresql 與 docker-compose 連接

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

我使用 docker-compose 用 postgresql 構建了一個燒瓶應用程序。 但是flask無法連接postgresql。 錯誤信息:

     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?

當我進入 docker 容器並 ping postgres-db ,它運行良好。 我啟動了燒瓶應用程序,它也運行良好。 僅當我使用 docker-compose up 時無法連接

我的 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

您遇到了爭用情況:應用程序試圖在數據庫可用之前連接到數據庫。 這不是 Docker 獨有的問題; 如果您的應用程序依賴於外部資源(如數據庫服務器),那么您需要編寫代碼來處理此類情況。

一個簡單的解決方案是在數據庫可用之前阻止應用程序的啟動。 在循環中運行諸如SELECT 1類的東西並等待它成功就足夠了。 執行此操作的示例 shell 腳本如下所示:

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

如果您在燒瓶應用程序中使用 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!')

以上在解決啟動競爭條件方面工作正常,但它不能處理在應用程序運行時數據庫服務器重新啟動的情況。 在這種情況下,您需要優雅地處理斷開/重新連接。 這需要在代碼設計方面做更多工作,並且超出了本答案的范圍。 有關此主題的一些討論,請參閱此答案

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM