FastAPI启动执行Alembic迁移遇容器停止及日志切换问题求助
解决FastAPI容器启动时执行Alembic迁移的问题
问题原因分析
- 容器停止:大概率是迁移执行过程中抛出未捕获的异常,导致FastAPI应用启动失败,容器随之退出;或者同步迁移操作阻塞了FastAPI的事件循环,引发启动异常。
- 日志被覆盖:Alembic默认的日志配置会修改全局日志设置,导致FastAPI的日志输出被替换或压制。
具体解决方案
1. 调整迁移执行逻辑,避免阻塞与异常崩溃
将同步的迁移操作放到线程池中执行,同时添加异常捕获,确保即使迁移失败,应用仍可正常启动(或按需终止):
from alembic.config import Config from alembic import command from fastapi import FastAPI from starlette.concurrency import run_in_threadpool import logging app = FastAPI() def run_migrations(): # 单独配置Alembic日志,避免干扰FastAPI日志 alembic_logger = logging.getLogger("alembic") alembic_logger.setLevel(logging.INFO) # 配置与FastAPI一致的日志格式 handler = logging.StreamHandler() formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s") handler.setFormatter(formatter) alembic_logger.addHandler(handler) alembic_logger.propagate = False # 禁止日志向根logger传播 # 加载Alembic配置并执行迁移 alembic_cfg = Config("alembic.ini") command.upgrade(alembic_cfg, "head") @app.on_event("startup") async def startup_event(): try: await run_in_threadpool(run_migrations) print("[Startup] 数据库迁移执行完成") except Exception as e: print(f"[Startup] 数据库迁移失败: {str(e)}") # 若需迁移失败则终止应用,取消下一行注释 # raise e
2. 修正Docker启动配置
确保Docker容器的启动命令是直接启动FastAPI应用,而非仅执行迁移。示例Dockerfile命令:
# 基础镜像、依赖安装等配置省略 CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--log-level", "info"]
3. 优化Alembic配置(可选)
修改alembic.ini中的日志配置,使其与FastAPI日志风格统一:
[loggers] keys = root,alembic [handlers] keys = console [formatters] keys = generic [logger_root] level = INFO handlers = console [logger_alembic] level = INFO handlers = console qualname = alembic propagate = 0 # 禁止向根logger传播 [handler_console] class = StreamHandler args = (sys.stderr,) formatter = generic [formatter_generic] format = %(asctime)s - %(levelname)s - %(name)s - %(message)s datefmt = %Y-%m-%d %H:%M:%S
验证效果
- 构建并启动容器后,日志会同时输出迁移过程和FastAPI启动日志,不会被覆盖。
- 若迁移执行成功,容器会持续运行FastAPI服务;若迁移失败,根据代码配置,要么继续运行服务,要么终止容器(按需选择)。
内容的提问来源于stack exchange,提问作者polohi
相关产品推荐
相关产品推荐

