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

Docker-Compose中FastAPI与PostgreSQL容器连接失败求助

Docker-Compose环境下FastAPI与PostgreSQL容器连接失败问题
  • 仅PostgreSQL容器化、本地运行FastAPI时可正常连接,两者都容器化后,在Base.metadata.create_all(bind=engine)代码处出现连接拒绝错误
  • 尝试修改main.py中的DATABASE_URL为postgresql://postgres:password@postgres:5433/fastapi_database后仍报错,不清楚配置文件管理方式

相关文件内容

Dockerfile

FROM python:3.10-slim
WORKDIR /app
COPY . .
RUN pip install --upgrade pip
RUN pip install "fastapi[all]" sqlalchemy psycopg2-binary

docker-compose.yml

version: '3.8'
services:
  ylab:
    container_name: ylab
    build:
      context: .
    entrypoint: >
      sh -c "uvicorn main:app --reload --host 0.0.0.0"
    ports:
      - "8000:8000"
  postgres:
    container_name: postgr
    image: postgres:15.1-alpine
    environment:
        POSTGRES_DB: "fastapi_database"
        POSTGRES_PASSWORD: "password"
    ports:
      - "5433:5432"

main.py

import fastapi as _fastapi
import sqlalchemy as _sql
import sqlalchemy.ext.declarative as _declarative
import sqlalchemy.orm as _orm

DATABASE_URL = "postgresql://postgres:password@localhost:5433/fastapi_database"
engine = _sql.create_engine(DATABASE_URL)
SessionLocal = _orm.sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = _declarative.declarative_base()

class Menu(Base):
    __tablename__ = "menu"
    id = _sql.Column(_sql.Integer, primary_key=True, index=True)
    title = _sql.Column(_sql.String, index=True)
    description = _sql.Column(_sql.String, index=True)

app = _fastapi.FastAPI()

# Create table 'menu'
Base.metadata.create_all(bind=engine)

报错信息

初始配置报错

sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) connection to server at "localhost" (127.0.0.1), port 5433 failed: Connection refused
ylab        |   Is the server running on that host and accepting TCP/IP connections?
ylab        | connection to server at "localhost" (::1), port 5433 failed: Cannot assign requested address
ylab        |   Is the server running on that host and accepting TCP/IP connections?

修改DATABASE_URL后报错

sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) connection to server at "postgres" (172.23.0.2), port 5433 failed: Connection refused
ylab        |   Is the server running on that host and accepting TCP/IP connections?

解决方案

1. 修正数据库连接端口

容器内部PostgreSQL使用默认端口5432,而非映射到宿主机的5433。修改main.py中的DATABASE_URL:

DATABASE_URL = "postgresql://postgres:password@postgres:5432/fastapi_database"

2. 配置容器依赖与网络

在docker-compose.yml中添加服务依赖,确保PostgreSQL容器先启动;同时显式配置网络(默认网络已互通,显式配置更清晰):

version: '3.8'
services:
  ylab:
    container_name: ylab
    build:
      context: .
    entrypoint: >
      sh -c "uvicorn main:app --reload --host 0.0.0.0"
    ports:
      - "8000:8000"
    depends_on:
      - postgres
    networks:
      - app-network
  postgres:
    container_name: postgr
    image: postgres:15.1-alpine
    environment:
        POSTGRES_DB: "fastapi_database"
        POSTGRES_PASSWORD: "password"
        POSTGRES_USER: "postgres"
    ports:
      - "5433:5432"
    networks:
      - app-network
networks:
  app-network:
    driver: bridge

3. 延迟数据库初始化

将表创建逻辑放到FastAPI启动事件中,避免PostgreSQL容器未就绪时执行初始化:
修改main.py:

# 保留原有代码...
app = _fastapi.FastAPI()

@app.on_event("startup")
def startup_event():
    Base.metadata.create_all(bind=engine)

4. 环境变量管理(推荐)

将数据库配置从代码中剥离,通过环境变量传递,避免硬编码:

  • 修改docker-compose.yml中ylab服务:
    environment:
      - DATABASE_URL=postgresql://postgres:password@postgres:5432/fastapi_database
    
  • 修改main.py读取环境变量:
    import os
    DATABASE_URL = os.getenv("DATABASE_URL", "postgresql://postgres:password@postgres:5432/fastapi_database")
    

内容的提问来源于stack exchange,提问作者Evgeny Romensky

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:11:11