Docker环境下FastAPI无法连接MySQL问题排查求助
FastAPI + Docker 连接 MySQL 故障排查
一、初始连接失败的常见原因
- 容器网络配置错误:Docker Compose中,FastAPI容器不能用
localhost作为MySQL主机名,必须使用compose配置里的MySQL服务名(比如mysql)——两个容器处于同一自定义网络,服务名会被自动解析为对应容器的IP。 - MySQL未完成初始化:FastAPI启动速度快于MySQL容器的初始化进程,导致连接时MySQL未就绪。需在compose中添加健康检查,确保MySQL就绪后再启动FastAPI:
services: mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DB} MYSQL_USER: ${MYSQL_USER} MYSQL_PASSWORD: ${MYSQL_PASSWORD} healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"] interval: 5s timeout: 5s retries: 5 fastapi: build: . env_file: .env depends_on: mysql: condition: service_healthy - 环境变量不匹配:.env文件中的
MYSQL_USER、MYSQL_PASSWORD、MYSQL_DB必须和MySQL容器的环境变量完全一致,同时确保compose通过env_file字段正确加载.env文件。 - MySQL权限限制:创建数据库用户时需允许从任意IP访问(不要仅限制
localhost),执行以下SQL:CREATE USER '${MYSQL_USER}'@'%' IDENTIFIED BY '${MYSQL_PASSWORD}'; GRANT ALL PRIVILEGES ON ${MYSQL_DB}.* TO '${MYSQL_USER}'@'%'; FLUSH PRIVILEGES;
二、修改连接字符串后出现 TypeError 的原因
- 连接字符串格式错误:SQLAlchemy连接MySQL的标准格式为
mysql+pymysql://<用户>:<密码>@<主机>:<端口>/<数据库名>,必须包含+pymysql指定驱动(前提是已安装pymysql包)。若拼接时存在类型不匹配(比如端口是整数类型),需转为字符串:from pydantic_settings import BaseSettings class Settings(BaseSettings): MYSQL_USER: str MYSQL_PASSWORD: str MYSQL_HOST: str MYSQL_PORT: int MYSQL_DB: str @property def database_url(self): return f"mysql+pymysql://{self.MYSQL_USER}:{self.MYSQL_PASSWORD}@{self.MYSQL_HOST}:{str(self.MYSQL_PORT)}/{self.MYSQL_DB}" settings = Settings() - 依赖包缺失:确保requirements.txt中包含
fastapi、uvicorn、sqlalchemy、pymysql、python-dotenv,Docker镜像构建时会自动安装这些依赖。 - 变量未正确加载:检查代码中是否正确读取.env变量,比如使用
python-dotenv或Pydantic Settings,避免变量为None导致拼接错误。
三、/post 接口 500 错误的排查
- 未捕获数据库异常:接口代码未处理数据库连接/操作异常,导致默认返回500错误。需添加异常捕获:
from fastapi import FastAPI, HTTPException, Depends from sqlalchemy.orm import Session from database import get_db app = FastAPI() @app.post("/post") def create_post(db: Session = Depends(get_db)): try: # 执行数据库操作 pass except Exception as e: raise HTTPException(status_code=400, detail=f"数据库操作失败: {str(e)}") - 数据库会话配置错误:检查
database.py中SessionLocal是否正确绑定引擎:from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from settings import settings engine = create_engine(settings.database_url) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) Base = declarative_base() def get_db(): db = SessionLocal() try: yield db finally: db.close()
四、快速验证步骤
- 进入FastAPI容器,执行
ping mysql验证网络连通性,能ping通则网络无问题。 - 在FastAPI容器内执行
mysql -h mysql -u ${MYSQL_USER} -p${MYSQL_PASSWORD} ${MYSQL_DB},手动连接MySQL,确认账号、密码、数据库名正确。 - 在
database.py中添加print(settings.database_url),启动容器后查看日志,确认连接字符串格式正确。 - 查看MySQL容器日志:
docker logs <mysql容器名>,检查是否有初始化失败、权限错误等日志。
内容的提问来源于stack exchange,提问作者PenAndPapers
相关产品推荐
相关产品推荐

