Docker部署FastAPI遇RuntimeError:asyncio.run不可在运行事件循环中调用
问题原因
你的核心问题出在main.py的main函数实现上:该函数内部直接调用了uvicorn.run()启动服务,而不是返回FastAPI应用实例。
当你通过uvicorn project_module.main:main命令启动时,uvicorn会将main函数视为应用工厂函数,尝试加载它并运行。但函数内部又再次调用uvicorn.run(),这会导致在已经运行的事件循环中再次执行asyncio.run(),从而触发RuntimeError: asyncio.run() cannot be called from a running event loop错误。
本地运行看似正常,大概率是你本地测试时的代码逻辑与部署版本不一致,或者误将python main.py(直接执行脚本启动)当成了uvicorn ...命令启动。
解决方案
有两种修复方式,任选其一即可:
方式1:修改main.py,让main函数返回FastAPI实例
调整main函数逻辑,使其作为应用工厂返回FastAPI对象,而非自行启动服务:
from fastapi import FastAPI app = FastAPI() # 你的路由和业务逻辑 @app.get("/") def read_root(): return {"Hello": "World"} # 应用工厂函数:返回FastAPI实例 def main(): return app # 仅在直接执行脚本时启动服务 if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=80)
方式2:直接指定FastAPI实例作为uvicorn入口
如果不需要应用工厂,可直接将app对象作为uvicorn的启动目标,同时修改Dockerfile的CMD命令:
- 修改
main.py,保留app实例的定义:
from fastapi import FastAPI app = FastAPI() @app.get("/") def read_root(): return {"Hello": "World"} # 本地直接执行脚本时启动服务 if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=80)
- 更新Dockerfile的CMD:
CMD ["uvicorn", "project_module.main:app", "--host", "0.0.0.0", "--port", "80"]
验证
修改完成后,重新构建Docker镜像并启动容器,即可解决该错误。部署到Heroku时,只需同步调整Procfile中的启动命令(对应上述两种方式之一)即可。
内容的提问来源于stack exchange,提问作者Amit
相关产品推荐
相关产品推荐

