Heroku部署FastAPI应用遇H10错误求助
解决Heroku部署FastAPI应用的H10崩溃错误
问题描述
部署FastAPI应用到Heroku后,通过Postman测试触发H10崩溃错误,日志如下:
2024-07-27T15:39:14.021635+00:00 heroku[web.1]: State changed from starting to crashed 2024-07-27T15:39:14.888419+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/api/v1/users" host=envy-app-database-4139c41d71a7.herokuapp.com request_id=8b66a3a8-2879-46c5-90db-2ab6d549c07c fwd="92.239.210.215" dyno= connect= service= status=503 bytes= protocol=https
应用在本地运行正常,配置文件如下:
requirements.txt
psycopg2==2.9.9 psycopg2-binary==2.9.9 aiofiles==23.2.1 aiogram==3.10.0 aiohttp==3.9.5 aiosignal==1.3.1 annotated-types==0.7.0 anyio==4.4.0 attrs==23.2.0 certifi==2024.7.4 click==8.1.7 colorama==0.4.6 dnspython==2.6.1 email_validator==2.2.0 fastapi==0.111.1 fastapi-cli==0.0.4 fastapi-utils==0.7.0 frozenlist==1.4.1 greenlet==3.0.3 gunicorn==22.0.0 h11==0.14.0 httpcore==1.0.5 httptools==0.6.1 httpx==0.27.0 idna==3.7 Jinja2==3.1.4 magic-filter==1.0.12 markdown-it-py==3.0.0 MarkupSafe==2.1.5 mdurl==0.1.2 multidict==6.0.5 mypy-extensions==1.0.0 packaging==24.1 psutil==5.9.8 pydantic==2.8.2 pydantic-settings==2.3.4 pydantic_core==2.20.1 Pygments==2.18.0 python-dotenv==1.0.1 python-multipart==0.0.9 PyYAML==6.0.1 rich==13.7.1 shellingham==1.5.4 sniffio==1.3.1 SQLAlchemy==2.0.31 starlette==0.37.2 typer==0.12.3 typing-inspect==0.9.0 typing_extensions==4.12.2 uvicorn==0.30.3 watchfiles==0.22.0 websockets==12.0 yarl==1.9.4
Procfile
web: uvicorn main:app --host=0.0.0.0 --port=${PORT:-5000}
main.py
import sys import os from controllers import user_controller, task_controller from database import engine from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from controllers.user_controller import * from models import user_model user_model.Base.metadata.create_all(bind=engine) app = FastAPI() origins = [ "http://localhost:3000", ] app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) app.include_router(user_controller.router, tags=['Users'], prefix='/api/v1/users') app.include_router(task_controller.router, tags=['Tasks'], prefix='/api/v1/tasks') @app.get("/") def read_root(): return {"Hello": "World"}
排查与解决方法
1. 获取完整崩溃日志
执行命令实时查看应用启动时的详细错误:
heroku logs --tail
H10错误只是表面现象,日志里会包含具体崩溃原因,比如数据库连接失败、依赖加载错误、代码语法问题等。
2. 修正数据库连接配置
Heroku提供的Postgres数据库地址是通过DATABASE_URL环境变量注入的,需要确保database.py中正确读取该变量,并且处理协议转换(SQLAlchemy要求用postgresql://而非Heroku默认的postgres://):
# database.py示例代码 import os from sqlalchemy import create_engine DATABASE_URL = os.getenv("DATABASE_URL") # 处理协议转换 if DATABASE_URL.startswith("postgres://"): DATABASE_URL = DATABASE_URL.replace("postgres://", "postgresql://", 1) engine = create_engine(DATABASE_URL)
3. 优化Procfile启动命令
改用gunicorn搭配uvicorn worker,提升生产环境稳定性:
web: gunicorn main:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:$PORT
4. 清理冗余依赖
- 移除
psycopg2,仅保留psycopg2-binary(Heroku上无需编译psycopg2,binary版本更适配) - 删除本地开发依赖:
colorama、watchfiles、fastapi-cli等,减少部署体积和潜在冲突
5. 调整数据库初始化时机
将数据库表创建逻辑移到FastAPI的启动事件中,避免启动前连接失败直接崩溃,同时增加错误日志:
# 修改main.py中的初始化代码 @app.on_event("startup") def startup_event(): try: user_model.Base.metadata.create_all(bind=engine) print("数据库表初始化成功") except Exception as e: print(f"数据库初始化失败: {str(e)}", file=sys.stderr) sys.exit(1)
删除原来的user_model.Base.metadata.create_all(bind=engine)直接调用。
6. 验证Heroku环境变量
执行命令检查所有配置的环境变量:
heroku config
确保DATABASE_URL存在且正确,其他必要的配置项(如密钥、API令牌)也已添加。
内容的提问来源于stack exchange,提问作者Константин Николаевич Бояр II
相关产品推荐
相关产品推荐

