部署在AWS Beanstalk的Python Flask应用遇502错误及端口占用问题求助
这种情况我之前帮别人排查过好几次,本质是没搞清楚AWS Beanstalk Python环境的默认运行逻辑导致的——咱们一步一步拆解:
问题根源
- Beanstalk的Python环境默认会用Gunicorn作为生产级的WSGI服务器,它自动就会监听8000端口,而且Nginx的配置也默认把用户的请求转发到8000端口。
- 你一开始让Flask应用监听5000端口,相当于自己启动了一个独立的开发服务器,但Nginx根本不知道这个服务,还是往8000发请求,自然就会返回502网关错误。
- 后来改成监听8000,又和Beanstalk自带的Gunicorn进程端口冲突,所以就报“地址已被占用”了。
正确的生产部署方式(强烈推荐)
不需要你手动启动Flask服务器,让Beanstalk用Gunicorn托管你的应用就好,只需要做两步配置:
确保
requirements.txt里包含依赖
在项目根目录创建或更新requirements.txt,把Flask和Gunicorn都加进去(版本可以根据你的需求调整):Flask==2.3.3 gunicorn==21.2.0创建
Procfile指定启动命令
同样在根目录创建一个名为Procfile(首字母必须大写)的文件,内容如下:web: gunicorn --workers=2 --bind=0.0.0.0:8000 app:app这里的
app:app要对应你的代码:第一个app是Flask实例所在的文件名(比如你的代码写在app.py里),第二个app是文件里创建的Flask对象(比如app = Flask(__name__))。如果你的文件叫main.py,实例叫my_flask_app,就改成main:my_flask_app。这样部署后,Beanstalk会自动启动Gunicorn服务,Nginx转发的请求也能正确到达,不会再出现502或者端口冲突的问题。
测试用方案(不适合生产环境)
如果只是想临时用Flask自带的开发服务器测试(注意:这个服务器性能差、不稳定,绝对不能用于生产),可以修改Beanstalk的配置来禁用Gunicorn:
在项目根目录创建.ebextensions文件夹,然后在里面新建00_flask_config.config文件,内容如下:
option_settings: aws:elasticbeanstalk:container:python: WSGIPath: app.py FlaskRunCommand: "--host=0.0.0.0 --port=8000"
这样Beanstalk就会直接用Flask的开发服务器启动,并且监听8000端口,和Nginx的转发配置匹配。
排查端口占用的小技巧
如果以后再碰到端口冲突,想确认哪个进程占了端口,可以通过SSH登录到Beanstalk对应的EC2实例,执行以下命令:
sudo lsof -i :8000
或者:
sudo netstat -tulpn | grep :8000
一般都会看到Gunicorn的进程,这就说明是Beanstalk默认的服务在运行,不需要你再手动启动Flask服务器啦。
内容的提问来源于stack exchange,提问作者Ming

