问题
最近需要使用AWS Elastic Beanstalk来部署Python的Flask后端web接口。这里先做一个最简单的Flask Hello,World接口服务程序。
Flask工程与代码
创建本地虚拟环境
conda create -n flask python=3.13
# 激活
conda activate flask
app.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
# run the app.
if __name__ == "__main__":
# Setting debug to True enables debug output. This line should be
# removed before deploying a production app.
app.debug = True
app.run()
requirements.txt
这个依赖库文件可以通过如下命令获得:
pip freeze > requirements.txt
内容如下:
blinker==1.9.0
click==8.1.8
Flask==3.1.0
itsdangerous==2.2.0
Jinja2==3.1.6
MarkupSafe==3.0.2
setuptools==75.8.0
Werkzeug==3.1.3
wheel==0.45.1
.ebextensions/python.config
option_settings:
aws:elasticbeanstalk:container:python:
WSGIPath: "app:app"
前面的app
表示模块app.py的文件名,后面的app
表示源代码里面导入的flask模块app。这一段配置WSGIPath: "app:app"
会在gunicorn
启动命令中生效。gunicorn是python的WSGI HTTP服务器,查看gunicorn官网可以知道这就是gunicorn的启动命令。其实,这行的作用就是在/var/app/current/Procfile
目录添加了gunicorn启动参数,具体如下图:
压缩源代码
在当前目录压缩源代码,具体命令如下:
zip -r flask-dev.zip . -x "*.idea*"
检查zip目录结构,命令如下:
zip -sf flask-dev.zip
zip目录结构如下:
Archive contains:
requirements.txt
.ebextensions/
.ebextensions/python.config
app.py
Total 4 entries (541 bytes)
注意,这个zip压缩文件的目录结构中,是没有一个统一的目录的,这个目录结构会影响gunicorn对这个python程序的调用的。
本地开发工作,到此为止就准备完成了。
配置ec2私钥文件
在EC2管理页面创建一个登录EC2机器的私钥文件即可,效果如下图:
创建安全组
这里我们放开22,80,8000端口,方便我们后续验证,创建安全组,如下图:
创建ec2角色
需要为AWS Elastic Beanstalk使用EC2实例,需要提供3种必要的权限,具体操作如下图:
在这个权限添加阶段,需要添加如下三个权限:
AWSElasticBeanstalkMulticontainerDocker
:AWS Elastic Beanstalk需要部署以docker方式,需要的权限;AWSElasticBeanstalkWebTier
:AWS Elastic Beanstalk需要部署Web服务方式,需要的权限;AWSElasticBeanstalkWorkerTier
:AWS Elastic Beanstalk需要部署后台任务处理,需要的权限。
添加AWS Elastic Beanstalk这三种需要的权限,为这个环境的EC2实例创建运行的角色即可。
还有另外一个叫aws-elasticbeanstalk-service-role
的角色,这个角色,我们后续可以通过AWS Elastic Beanstalk后面的操作创建应用程序的时候创建。
配置AWS Elastic Beanstalk
我们先通过顶部页面搜索,找到Amazon Elastic Beanstalk产品首页,先点击创建应用程序按钮,开始AWS Elastic Beanstalk的配置。如下图:
开始创建一个新的应用程序与环境,具体如下图:
**注意:**这里我只是简单演示,就是手动上传了之前准备好的源代码zip压缩文件。正常生产环境来说,应该是通过CI/CD工作流来处理的。
配置服务访问权限,如下图:
这里就是关于EC2角色的配置,以及eb使用的角色权限,还用上了之前我们提前配置好的ec2角色和密钥对。接下来就是设置网络和数据库之类的东西了,具体如下图:
由于这里只是对于aws eb的一个初步了解和入门性质的使用,我们就按最简的方式来处理了。如果生产环境处理,往往不可这样操作,生产环境中应用服务的ec2实例,应该是在私有内网中,而且,应当事先,准备好环境以及数据库。
这里就是一个eb的入门。所以,我们这里就用最简单的方式,配置一个使用默认的vps安全组即可。后续,eb创建这个python应用程序的过程中,会主动创建一个安全组的,那个安全组主要放开了22端口和80端口。
- 22端口,主要是给ssh用
- 80端口,主要是给nginx作为出入口。
其他都用默认免费ec2类型即可。接下来配置监控配置,我们也配置最简单的,如下图:
这里我们也继续选择最简配置。注意这里使用了nginx作为代理程序,还配置了一个Py的环境变量——PYTHONPATH,关于这个变量就是AWS EC2使用Python3的位置。我们这个Flask程序部署的整体架构如下图:
这就是使用eb部署后的Py的Web架构。
审核通过后,直接提交,等待一段时间即可。
测试验证
等待一段时间,发现应用程序部署完成了,环境运行状态变成Green,且出现了部署完成的事件,则表示应用程序部署完成了。如下图:
应用程序部署完成后,我们就可以开始手动登录到EC2实例中去验证。正常来说,你可以直接点击上面的域进行验证,但是,AWS中国的账号如果域名没有备案通过,AWS中国的80端口是不能使用的,即使安全组放开了80端口,也没有用。所以,我们现在只能通过EC2实例本地验证页面访问效果了。打开EC2页面找到,刚才通过eb创建的ec2实例,直接使用页面方式登录进去,如下图:
打开连接方式页面后,随便选择一种连接方式即可:
这里我直接选择网页版直接SSH登录了。登录成功效果如下图:
直接使用如下命令:
curl http://127.0.0.1:80
效果如下:
看到了hello,world说明nginx代理的Py应用程序部署成功。也可以发送如下命令来验证一下gunicorn服务器:
curl http://127.0.0.1:8000
效果如下:
总结
aws中国的账号,如果没有域名通过备案的话。就算安全组中放开了端口,都不一定生效的。AWS Elastic Beanstalk能减少我们去手动创建auto scaling组,安全组,lb等其他一堆aws云服务的工作量。所以eb对于毕竟熟悉aws云的老手来说,还是挺省工作量的。
参考
- Host Python Flask app on AWS ElasticBeanstalk
- gunicorn
- Gunicorn百科
- Deploying a Flask Application to Elastic Beanstalk
- 将 Django 应用程序部署到 Elastic Beanstalk
- 在 Elastic Beanstalk 上使用 Procfile 配置 WSGI 服务器
- 面向所有环境的常规选项
- Deploying a Flask App to AWS Elastic Beanstalk
- 将 Flask 应用程序部署到 Elastic Beanstalk
- Using the Elastic Beanstalk Python platform
- Platform specific options
- The python3 executable
- Deploy Flask to Amazon Elastic Beanstalk
- Running Gunicorn
- Configuring the WSGI server with a Procfile on Elastic Beanstalk
- PYTHONPATH