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
相关产品推荐
相关产品推荐

