Heroku部署Flask API报Port 5000 Address already in use如何解决
核心报错原因
你遇到的Address already in use、Port 5000 is in use报错,90%以上的情况是硬编码了固定监听端口导致的:Heroku平台不会固定开放5000端口,会在应用启动时动态分配一个可用端口,通过系统环境变量PORT传给应用,平台的路由层只会把请求转发到这个动态分配的端口上。你手动修改固定端口(不管改成5000还是其他数值)都不符合平台规则,要么和平台预留端口冲突,要么根本没在平台要求的端口上监听,自然会报错、无法访问。
分步排查解决
第一步:修正Flask启动代码,删除所有硬编码端口的逻辑
本地开发可以默认用5000端口,线上必须读取环境变量的动态端口,同时必须绑定0.0.0.0地址,否则容器内服务无法被外部访问。正确的启动代码参考:import os from flask import Flask app = Flask(__name__) # 你的路由逻辑写在这里 if __name__ == "__main__": # 优先读取Heroku动态分配的PORT,本地调试默认用5000 listen_port = int(os.environ.get("PORT", 5000)) app.run(host="0.0.0.0", port=listen_port)注意不要在代码里手动给
os.environ["PORT"]赋值固定值,会覆盖平台传入的配置直接触发冲突。第二步:检查Procfile启动配置,不要写死启动端口
项目根目录的Procfile是Heroku的启动命令配置文件,常见错误是在启动命令里硬写了绑定端口,比如web: gunicorn app:app -b 127.0.0.1:5000。
正确的配置不需要手动指定端口,Gunicorn会自动读取Heroku的PORT环境变量,参考写法:web: gunicorn app:app如果需要手动指定绑定参数,必须引用环境变量,不能写死数值:
web: gunicorn app:app -b 0.0.0.0:$PORT同时检查Procfile里不要写多个启动服务进程的命令,比如同时启动Flask自带开发服务器和Gunicorn,两个进程会争抢端口直接触发报错。
第三步:排查重复启动逻辑
检查项目代码里有没有多处调用app.run()的情况,比如除了主入口文件,其他依赖模块里误写了服务启动代码,会导致启动时拉起多个服务进程抢端口。如果开启了Flask debug模式,先临时关闭debug模式排除重载器异常拉起多进程的问题。第四步:确认修改生效
所有配置改完后,必须把变更commit到Git仓库,再推送到Heroku远程分支,否则线上运行的还是旧版本代码。推送完成后可以通过日志命令查看启动状态,确认服务监听的是平台随机分配的端口,而非固定的5000。
内容的提问来源于stack exchange,提问作者AdekunleCodez

