You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用docker compose启动FastAPI+PostgreSQL服务报连接被拒错误

根因说明

从你的运行日志可以直接定位核心问题:Docker Compose的depends_on配置仅保证PostgreSQL容器的启动顺序在API容器之前,不会等待PostgreSQL服务完成初始化、能够接受TCP连接。你贴的日志中API容器报错退出后,PostgreSQL才输出database system is ready to accept connections的就绪日志,完全符合这个问题的特征。
除此之外你还存在配置不匹配的问题,也需要同步修复。

解决步骤

1. 修复服务启动顺序问题

两种常用方案任选其一即可:

  • 方案A:添加启动等待脚本
    首先在项目根目录新建wait-for-db.sh文件,内容如下:

    #!/bin/sh
    set -e
    
    until PGPASSWORD=$DATABASE_PASSWORD psql -h "$DATABASE_HOST" -U "$DATABASE_USERNAME" -d "$DATABASE_NAME" -c '\q'; do
      >&2 echo "PostgreSQL 还未就绪,等待中..."
      sleep 1
    done
    
    >&2 echo "PostgreSQL 已就绪,启动服务"
    exec "$@"
    

    修改Dockerfile,添加psql客户端依赖:

    RUN apt-get update \
        && apt-get -y install libpq-dev gcc postgresql-client \
        && pip install psycopg2
    

    给脚本添加执行权限后,修改docker-compose.yaml中rest_api的启动命令:

    rest_api:
      build: .
      command: sh -c "./wait-for-db.sh uvicorn app.main:app --host 0.0.0.0"
      # 其余原有配置保持不变
    
  • 方案B:用健康检查控制启动顺序
    直接修改docker-compose.yaml,给db服务添加健康检查,同时调整rest_api的依赖逻辑:

    services:
      db:
        image: postgres:13-alpine
        # 原有配置保持不变
        healthcheck:
          test: ["CMD-SHELL", "pg_isready -U ${DATABASE_USERNAME} -d ${DATABASE_NAME}"]
          interval: 2s
          timeout: 2s
          retries: 10
    
      rest_api:
        # 原有配置保持不变
        depends_on:
          db:
            condition: service_healthy
    

2. 修复配置不一致问题

  • 修正docker-compose.yaml中db服务的错误环境变量,你当前把POSTGRES_USER的值设为了${DATABASE_TYPE}(一般这个变量值是postgresql,会导致数据库初始化的用户名不符合预期),修改后如下:
    db:
      environment:
        POSTGRES_USER: ${DATABASE_USERNAME}
        POSTGRES_PASSWORD: ${DATABASE_PASSWORD}
        POSTGRES_DB: ${DATABASE_NAME}
    
  • 取消database.py中从环境变量读取连接串代码的注释,不要硬编码连接信息,避免本地配置和容器配置不匹配:
    load_dotenv()
    db_type = os.getenv("DATABASE_TYPE")
    username = os.getenv("DATABASE_USERNAME")
    password = os.getenv("DATABASE_PASSWORD")
    host = os.getenv("DATABASE_HOST")
    port = os.getenv("DATABASE_PORT")
    name = os.getenv("DATABASE_NAME")
    
    SQLALCHEMY_DATABASE_URI = f"{db_type}://{username}:{password}@{host}:{port}/{name}"
    
    确认你的.env文件中DATABASE_HOST配置为db,DATABASE_PORT配置为5432。

3. 检查Dockerfile路径配置

你提到Dockerfile位于./app目录下,但docker-compose里rest_api的build上下文默认是项目根目录,如果实际Dockerfile确实在app目录下,需要修改build配置:

rest_api:
  build:
    context: .
    dockerfile: ./app/Dockerfile
  # 其余原有配置保持不变

验证操作

修改完成后先清理旧的容器和数据卷,避免残留的旧PostgreSQL数据影响验证:

docker compose down -v
docker compose up --build

内容的提问来源于stack exchange,提问作者Daniel Qiao

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 12:36:03