简介
本系列的前四篇文章中,我们使用Python的Flask框架开发了一个简单的天气预报网站,并且可以用Docker把这个网站部署到了私有服务器上,使得我们的网站可以在公网上访问。
但是并不是所有人都有自己的服务器,为了使网站的部署更加简单,我们可以使用AWS或者Google Cloud这样的云服务提供商提供的云服务器来部署我们的网站。
前置条件
- 已经会用Flask框架开发简单的Web应用程序(参见“Python Web开发学习(一):使用Flask框架”)
- 已经安装好PostgreSQL数据库,并且会使用SQLAlchemy操作数据库(参见“Python Web开发学习(二):使用PostgreSQL和SQLAlchemy”
- 已经有AWS的账号,并且会使用它们提供的云服务器
- 已经有一个域名
扩展
- 若想了解如何通过输入框获取用户输入,以及如何使用API获取网络上的信息,请参见“Python Web开发学习(三):使用输入框和API”
- 若想了解如何使用Docker部署网站,请参见“Python Web开发学习(四):使用Docker、Gunicorn和Nginx部署网站”
部署到AWS
总的来说,部署到AWS有以下几个步骤:
- 创建AWS账号并获取Access Key和Secret Key
- 配置AWS命令行工具
- 创建安全组
- 创建数据库
- 创建App的容器镜像
- 创建App Runner
创建AWS账号并获取Access Key和Secret Key
-
首先,我们需要在AWS官网上注册一个账号,然后在控制台中创建一个新的IAM用户。可以在顶端的搜索框中搜索“IAM”找到IAM服务。
-
在IAM服务中,选择“用户”,然后点击“添加用户”。
- 用户名可以任取,不需要勾选“Enable console access“
- 勾选”AdministratorAccess“权限
- 检查之后选择创建即可
-
创建成功后进入用户详情页,选择“安全凭证”选项卡,点击“创建访问密钥”。
- 创建时勾选“Command Line Interface”选项
- 点击“Next“按钮创建
- 找个安全的地方记录Access Key和Secret Key,这两个Key只会显示一次,如果忘记了Secret Key,只能重新创建新的Access Key
配置AWS命令行工具
为了方便使用AWS的服务,避免在网页上做那些繁琐的操作,我们可以使用AWS提供的命令行工具来管理我们的云服务器。
-
安装AWS命令行工具
可参见AWS官方文档安装AWS命令行工具,注意选择适合自己操作系统的安装方式。
安装完成后,可以在命令行中输入
aws --version
来检查是否安装成功。 -
配置AWS命令行工具
在命令行中输入
aws configure
,然后输入刚才创建的Access Key和Secret Key,以及默认的区域和输出格式。1 2 3 4 5
$ aws configure AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY Default region name [None]: us-west-2 Default output format [None]: json
配置完成后,可以在命令行中输入
aws configure list
来查看配置信息。1
aws configure list
创建安全组
AWS对于云服务的安全性有很高的要求,我们需要创建一个安全组来控制访问我们的云服务器的规则。这里主要是为了允许从外部通过3306端口访问我们接下来要创建的MySQL数据库。
-
在AWS控制台中搜索“security group”,进入安全组页面。
-
点击“创建安全组”。
- 安全组名称:可以任取,比如“flask-weather”
- 描述:可以不填
- VPC:选择默认的VPC
- 添加规则:添加规则,允许TCP协议,端口3306,来源为“Anywhere”
- 最后点击“创建安全组”
创建数据库
接下来我们需要在AWS上创建一个数据库,用来存储我们的网站的数据。AWS提供的数据库托管服务叫做RDS。
-
在AWS控制台中搜索“RDS”,进入RDS服务页面。
-
点击“创建数据库”。
- 选择数据库创建方式:选择“标准创建”
- 选择数据库引擎:选择MySQL
- 选择数据库实例大小:选择“Free tier”
- 设置数据库实例标识符、主用户名和密码
- 设置数据库实例类别、存储、VPC、子网组、安全组等,这里选择刚才创建的安全组
- 最后点击“创建数据库”
-
创建数据库需要一些时间,等待数据库创建完成后,可以在数据库的详情页中找到数据库的端点,然后可以使用一些数据库连接工具连接数据库。
我常用的数据库连接工具是VS Code的插件MySQL,可以在VS Code中直接连接数据库,非常方便。
图片来源:database-client.com
如果你使用JetBrains的IDE(如IntelliJ IDEA),也可以使用IDE自带的数据库工具连接数据库。
创建App的容器镜像
现代的Web应用程序一般都是使用容器技术部署的,我们可以使用Docker来创建一个容器镜像,然后把这个镜像部署到AWS提供的App Runner上。
-
首先,我们需要在AWS上创建一个ECR(Elastic Container Registry)来存储我们的容器镜像。
在AWS控制台中搜索“ECR”,进入ECR服务页面。
点击“创建存储库”。
- 存储库名称:可以任取,比如“flask-weather”
- 标签:可以不填
- 加密:可以不填
- 最后点击“创建存储库”
创建完成后记录存储库的URI,后面会用到。
-
在本地的项目目录中创建一个Dockerfile文件,用来构建容器镜像。
1 2 3 4 5 6 7 8 9 10
FROM python:3.9-slim WORKDIR /app COPY requirements.txt requirements.txt RUN pip install -r requirements.txt COPY . . CMD ["gunicorn", "-b", "0.0.0.0:5001", "app:app"]
这个Dockerfile文件的内容和之前使用Docker部署网站的Dockerfile文件内容基本一样,只是这里使用了Python 3.9的slim版本作为基础镜像。
-
在项目目录中创建一个requirements.txt文件,用来记录项目的依赖。
1 2 3 4 5
Flask==2.0.1 Flask-SQLAlchemy==2.5.1 gunicorn==20.1.0 psycopg2-binary==2.9.1 requests==2.26.0
这个文件的内容和之前使用Docker部署网站的requirements.txt文件内容基本一样,只是这里使用了Flask 2.0.1版本。
-
在项目目录中创建一个
.dockerignore
文件,用来忽略一些不需要的文件。1 2 3 4 5 6 7 8 9 10 11
__pycache__ *.pyc *.pyo *.pyd .DS_Store .env .venv .git .gitignore .dockerignore .vscode
-
构建容器镜像
在项目目录中执行以下命令构建容器镜像。
1
docker build -t flask-weather .
这个命令会在本地构建一个名为
flask-weather
的容器镜像。 -
推送容器镜像到ECR
首先,我们需要登录到ECR。
1
aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-west-2.amazonaws.com
这个命令会获取ECR的登录密码,然后使用Docker登录到ECR。
接下来,我们需要给容器镜像打上标签。
1
docker tag flask-weather:latest 123456789012.dkr.ecr.us-west-2.amazonaws.com/flask-weather:latest
这个命令会给本地的
flask-weather
容器镜像打上标签,然后推送到ECR。1
docker push 123456789012.dkr.ecr.us-west-2.amazonaws.com/flask-weather:latest
这个命令会把本地的
flask-weather
容器镜像推送到ECR。推送完成后,可以在ECR的存储库中看到刚才推送的容器镜像。
创建App Runner
我们使用AWS提供的App Runner来部署我们的网站。
-
在AWS控制台中搜索“App Runner”,进入App Runner服务页面。
-
点击“创建服务”。
- 选择部署方式:选择“容器”
- 选择容器镜像:选择刚才推送到ECR的容器镜像
- 选择端口:选择5001
- 点击“下一步”
-
配置服务
- 服务名称:可以任取,比如“flask-weather”
- 环境变量:添加数据库的连接信息,如
DATABASE_URL
、DATABASE_USER
、DATABASE_PASSWORD
等 - 点击“下一步”
-
配置网络
- VPC:选择默认的VPC
- 子网:选择默认的子网
- 安全组:选择刚才创建的安全组
- 点击“下一步”
-
配置域名
- 域名:可以任取,比如“flask-weather”
- 点击“下一步”
-
部署服务
- 点击“部署服务”
部署完成后,可以在App Runner的服务页面中看到刚才创建的服务。
点击服务名称,可以看到服务的详情,包括服务的域名。
点击服务的域名,可以在浏览器中访问我们的网站。
定制域名
在完成上面的部署之后,我们可以通过AWS App Runner提供的域名来访问我们的网站,但是AWS提供的域名一般比较长,而且会包含一段随机的字符串,不太好记忆,我们可以将在App Runner上部署的网站绑定到我们自己的域名上。
直接在App Runner上绑定自己的域名会报错“Create Failed”,原因是App Runner需要为我们的域名颁发证书以使用HTTPS,但是我们的域名并没有把Amazon列为受信任的证书颁发机构。我们需要在域名的DNS服务器上添加CAA记录,以便App Runner可以为我们的域名颁发证书。
-
证书颁发机构授权(CAA)记录
在域名的DNS服务器上添加CAA记录,CAA记录的名称选择
@
,值为amazon.com
。这表示Amazon可以为我们的域名下任意的子域名颁发证书。 -
在App Runner上绑定域名
在App Runner的服务页面中,点击服务名称,然后点击“域名”选项卡,点击“绑定域名”。
- 域名:输入我们自己的域名
- 点击“绑定域名”
绑定完成后,可以在浏览器中访问我们的网站。