Docker部署FastAPI应用遇ConnectionRefusedError[Errno111]连接拒绝问题
解决FastAPI+Docker环境下PostgreSQL连接拒绝问题
核心问题1:数据库连接地址错误
在Docker Compose的内部网络中,容器之间通过服务名进行通信,而非localhost。你的.env文件中DATABASE_URL使用了localhost,这会导致web、migrate容器尝试连接自身内部的PostgreSQL(但容器内并未安装),从而触发连接拒绝错误。
修改.env中的数据库连接地址
将原配置:
DATABASE_URL=postgresql+asyncpg://postgres:55555@localhost/test_db
替换为:
DATABASE_URL=postgresql+asyncpg://postgres:55555@db/test_db
这里的db是docker-compose.yml中定义的PostgreSQL服务名,容器间可直接通过该名称解析到数据库容器的IP地址。
核心问题2:PostgreSQL未完全就绪时发起连接
depends_on: - db仅能保证db容器启动,但PostgreSQL服务需要几秒时间完成初始化才能接受连接。migrate和web服务可能在数据库未就绪时就尝试连接,导致失败。
解决方法:添加健康检查+启动依赖条件
修改docker-compose.yml,为db服务添加健康检查,让migrate和web仅在数据库就绪后启动:
version: '3.8' services: db: image: postgres:14 restart: always environment: POSTGRES_USER: ${POSTGRES_USER} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB} volumes: - postgres_data:/var/lib/postgresql/data # 添加健康检查,验证PostgreSQL服务是否就绪 healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"] interval: 5s timeout: 5s retries: 5 migrate: build: . command: poetry run alembic upgrade head volumes: - .:/app depends_on: # 等待db服务进入健康状态后再启动 db: condition: service_healthy environment: DATABASE_URL: ${DATABASE_URL} web: build: . command: poetry run uvicorn app.main:app --host 0.0.0.0 --port 8000 volumes: - .:/app ports: - "8000:8000" depends_on: # 等待db服务就绪 db: condition: service_healthy # 等待数据库迁移完成后再启动API服务 migrate: condition: service_completed_successfully environment: DATABASE_URL: ${DATABASE_URL} SECRET_KEY: ${SECRET_KEY} ALGORITHM: ${ALGORITHM} ACCESS_TOKEN_EXPIRE_MINUTES: ${ACCESS_TOKEN_EXPIRE_MINUTES} volumes: postgres_data:
配置说明:
healthcheck通过pg_isready命令检查PostgreSQL服务状态,每5秒检查一次,最多重试5次,确保数据库完全就绪。service_healthy条件确保migrate、web服务仅在db服务健康(可接受连接)后启动。service_completed_successfully条件确保web服务在数据库迁移任务完成后再启动,避免API服务提前运行导致的异常。
验证修复
执行以下命令重新部署服务:
docker-compose down -v # 停止并清理旧容器、数据卷 docker-compose up --build # 重新构建镜像并启动所有服务
完成后访问http://127.0.0.1:8000/docs尝试创建用户,连接拒绝问题即可解决。
内容的提问来源于stack exchange,提问作者123 123
相关产品推荐
相关产品推荐

