@@ -10,25 +10,28 @@ Web 程序通常有两种部署方式:传统部署和云部署。传统部署
1010首先,我们需要生成一个依赖列表,方便在部署环境里安装。使用下面的命令把当前依赖列表写到一个 requirements.txt 文件里:
1111
1212``` bash
13- (env ) $ pip freeze > requirements.txt
13+ (.venv ) $ pip freeze > requirements.txt
1414```
1515
16- 对于某些配置,生产环境下需要使用不同的值。为了让配置更加灵活,我们把需要在生产环境下使用的配置改为优先从环境变量中读取,如果没有读取到,则使用默认值 :
16+ 对于某些配置,生产环境下需要使用不同的值。这是我们之前为生产环境创建的配置类 :
1717
1818``` python
19- app.config[ ' SECRET_KEY ' ] = os.getenv( ' SECRET_KEY ' , ' dev ' )
20- app.config[ ' SQLALCHEMY_DATABASE_URI ' ] = prefix + os.path.join(os.path.dirname(app.root_path), os.getenv(' DATABASE_FILE ' , ' data.db' ))
19+ class ProductionConfig ( BaseConfig ):
20+ SQLALCHEMY_DATABASE_URI = os.getenv(' DATABASE_URL ' , SQLITE_PREFIX + str ( BASE_DIR / ' data.db' ))
2121```
2222
23- 以第一个配置变量为例, ` os.getenv('SECRET_KEY', 'dev') ` 表示读取系统环境变量 ` SECRET_KEY ` 的值,如果没有获取到,则使用 ` dev ` 。
23+ 在示例程序里,因为我们部署后将继续使用 SQLite,所以只需要为生产环境设置不同的数据库文件名。另外,继承自 BaseConfig 的配置 SECRET_KEY 需要改为使用随机字符:
2424
25- > ** 注意** 像密钥这种敏感信息,保存到环境变量中要比直接写在代码中更加安全。
25+ ``` python
26+ class BaseConfig :
27+ SECRET_KEY = os.getenv(' SECRET_KEY' , ' dev' )
28+ ```
2629
27- 对于第二个配置变量,我们仅改动了最后的数据库文件名。在示例程序里,因为我们部署后将继续使用 SQLite,所以只需要为生产环境设置不同的数据库文件名,否则的话,你可以像密钥一样设置优先从环境变量读取整个数据库 URL 。
30+ 在生产环境,为了安全考虑,需要把具体的值作为环境变量定义,而不是放到代码里。我们将在远程服务器环境创建新的 .env 文件写入 SECRET_KEY 的值,具体将在下一节介绍 。
2831
29- 在部署程序时,我们不会使用 Flask 内置的开发服务器运行程序,因此,对于写到 .env 文件的环境变量,我们需要手动使用 python-dotenv 导入。下面在项目根目录创建一个 wsgi.py 脚本,在这个脚本中加载环境变量,并导入程序实例以供部署时使用 :
32+ 在部署程序时,我们不会使用 Flask 内置的开发服务器运行程序,因此,对于写到 .env 文件的环境变量,我们需要手动使用 python-dotenv 导入。下面在项目根目录创建一个 wsgi.py 脚本,作为生产环境的程序入口脚本。我们在这个脚本中加载环境变量,并创建程序实例以供部署时使用 :
3033
31- * wsgi.py:手动设置环境变量并导入程序实例 *
34+ * wsgi.py:手动设置环境变量并创建程序实例 *
3235
3336``` python
3437import os
@@ -39,10 +42,10 @@ dotenv_path = os.path.join(os.path.dirname(__file__), '.env')
3942if os.path.exists(dotenv_path):
4043 load_dotenv(dotenv_path)
4144
42- from watchlist import app
43- ```
45+ from watchlist import create_app
4446
45- 这两个环境变量的具体定义,我们将在远程服务器环境创建新的 .env 文件写入。
47+ app = create_app(config_name = ' production' )
48+ ```
4649
4750最后让我们把改动提交到 Git 仓库,并推送到 GitHub 上的远程仓库:
4851
@@ -52,14 +55,11 @@ $ git commit -m "Ready to deploy"
5255$ git push
5356```
5457
55- > ** 提示** 你可以在 GitHub 上查看本书示例程序的对应 commit:[ 92eabc8] ( https://github.com/helloflask/watchlist/commit/92eabc89a669a8b3e2d2a56177a875938923fd52 ) 。
56-
57-
5858## 使用 PythonAnywhere 部署程序
5959
6060首先访问[ 注册页面] ( https://www.pythonanywhere.com/registration/register/beginner/ ) 注册一个免费账户。注册时填入的用户名将作为你的程序域名的子域部分,以及分配给你的 Linux 用户名。比如,如果你的用户名为 greyli,最终为你分配的程序域名就是 < http://greyli.pythonanywhere.com/ > 。
6161
62- 注册完成后会有一个简单的教程,你可以跳过,也可以跟着了解一下基本用法。管理面板主页如下所示 :
62+ 注册完成后会有一个简单的教程,你可以跳过,也可以跟着了解一下基本用法。管理面板(Dashboard)主页如下所示 :
6363
6464![ 管理面板主页] ( images/11-1.png )
6565
@@ -71,7 +71,7 @@ $ git push
7171- Tasks(任务):创建计划任务
7272- Databases(数据库):设置数据库,免费账户可以使用 MySQL
7373
74- 这些链接对应页面的某些功能也可以直接在管理面板主页打开 。
74+ 这些链接对应页面的某些功能也可以直接在管理面板主页对应部分打开 。
7575
7676我们需要先来创建一个 Web 程序,你可以点击导航栏的 Web 链接,或是主页上的“Open Web tab”按钮打开 Web 面板:
7777
@@ -85,7 +85,7 @@ $ git push
8585
8686![ 选择 Web 框架] ( images/11-4.png )
8787
88- 接着选择你想使用的 Python 版本:
88+ 接着选择你想使用的 Python 版本(最低需要 3.9 版本) :
8989
9090![ 选择 Python 版本] ( images/11-5.png )
9191
@@ -103,7 +103,7 @@ $ git push
103103* 从 GitHub 拉取我们的程序
104104* 在本地将代码存储为压缩文件,然后在 Files 标签页上传压缩包
105105
106- 因为我们的代码已经推送到 GitHub 上,这里将采用第一种方式。首先通过管理面板主页的“Bash”按钮或是 Consoles 面板下的“Bash”链接创建一个命令行会话:
106+ 因为我们的代码已经推送到 GitHub 上,这里将采用第一种方式。首先通过管理面板主页的“Bash”按钮或是 Consoles 面板下的“Bash”链接创建一个命令行会话,后续的命令都需要在新打开的会话中执行 :
107107
108108![ 打开新的命令行会话] ( images/11-7.png )
109109
@@ -116,11 +116,11 @@ $ cd watchlist # 切换进程序仓库
116116
117117这会把程序代码克隆到 PythonAnywhere 为你分配的用户目录中,路径即 ` /home/你的 PythonAnywhere 用户名/你的仓库名称 ` ,比如 ` /home/greyli/watchlist ` 。
118118
119- 注意替换 git clone 命令后的 Git 地址,将 ` greyli ` 替换为你的 GitHub 用户名,将 ` watchlist ` 替换为你的仓库名称。
119+ 注意替换 git clone 命令后的 Git 地址,将 ` helloflask ` 替换为你的 GitHub 用户名,将 ` watchlist ` 替换为你的仓库名称。
120120
121121> ** 提示** 如果你在 GitHub 上的仓库类型为私有仓库,那么需要将 PythonAnywhere 服务器的 SSH 密钥添加到 GitHub 账户中,具体参考第 1 章“设置 SSH 密钥”小节。
122122
123- 下面我们在项目根目录创建 .env 文件,并写入生产环境下需要设置的两个环境变量。其中, 密钥(` SECRET_KEY ` )的值是随机字符串 ,我们可以使用 uuid 模块来生成:
123+ 下面我们在项目根目录创建 .env 文件,并写入生产环境下需要设置的环境变量。 密钥(` SECRET_KEY ` )的值需要为随机字符串 ,我们可以使用 uuid 模块来生成。在你本地的终端中打开 Python Shell 并执行相应代码 :
124124
125125``` python
126126$ python3
@@ -129,30 +129,33 @@ $ python3
129129' 3d6f45a5fc12445dbac2f59c3b6c7cb1'
130130```
131131
132- 复制生成的随机字符备用,接着创建 .env 文件:
132+ 复制生成的随机字符备用,接着回到 PythonAnywhere 上打开的命令行会话,执行下面的命令创建 .env 文件:
133133
134134``` bash
135135$ nano .env
136136```
137137
138- 写入设置密钥和数据库名称的环境变量 :
138+ 写入设置密钥的环境变量(按下 Control+O 和 Enter 保存,然后按下 Control+X 退出) :
139139
140140``` ini
141141SECRET_KEY =3d6f45a5fc12445dbac2f59c3b6c7cb1
142- DATABASE_FILE =data-prod.db
143142```
144143
145144最后安装依赖并执行初始化操作:
146145
147146``` bash
148- $ python3 -m venv env # 创建虚拟环境
149- $ . env /bin/activate # 激活虚拟环境
150- (env ) $ pip install -r requirements.txt # 安装所有依赖
151- (env ) $ flask init-db # 初始化数据库
152- (env ) $ flask admin # 创建管理员账户
147+ $ python3 -m venv .venv # 创建虚拟环境
148+ $ source .venv /bin/activate # 激活虚拟环境
149+ (.venv ) $ pip install -r requirements.txt # 安装所有依赖
150+ (.venv ) $ flask init-db # 初始化数据库,也可以执行 flask forge 创建虚拟数据
151+ (.venv ) $ flask admin # 创建管理员账户
153152```
154153
155- 先不要关闭这个标签页,后面我们还要在这里执行一些命令。点击右上角的菜单按钮,并在浏览器的新标签页打开 Web 面板。
154+ 你的命令行窗口和依次输入的命令(省略了后两条命令)类似下图:
155+
156+ ![ 代码配置] ( images/11-8.png )
157+
158+ 先不要关闭这个标签页,后面我们还要在这里执行一些命令。点击右上角的菜单按钮,并在浏览器的后台标签页打开 Web 面板。
156159
157160
158161## 设置并启动程序
@@ -162,9 +165,9 @@ $ . env/bin/activate # 激活虚拟环境
162165
163166### 代码
164167
165- 回到 Web 标签页,先来设置 Code 部分的配置:
168+ 切换到 Web 面板( 标签页) ,先来设置 Code 部分的配置:
166169
167- ![ 代码配置] ( images/11-8 .png )
170+ ![ 代码配置] ( images/11-9 .png )
168171
169172点击源码(Source code)和工作目录(Working directory)后的路径并填入项目根目录,目录规则为“/home/用户名/项目文件夹名”。
170173
@@ -189,36 +192,36 @@ PythonAnywhere 会自动从这个文件里导入名称为 `application` 的程
189192
190193为了让程序正确运行,我们需要在 Virtualenv 部分填入虚拟环境文件夹的路径:
191194
192- ![ 虚拟环境配置] ( images/11-9 .png )
195+ ![ 虚拟环境配置] ( images/11-10 .png )
193196
194- 对应我们的项目就是 ` /home/greyli/watchlist/env / ` ,注意替换其中的用户名、项目名称和虚拟环境名称部分。点击 Virtualenv 部分的红色字体链接,填入并保存。
197+ 对应我们的项目就是 ` /home/greyli/watchlist/.venv / ` ,注意替换其中的用户名、项目名称和虚拟环境名称部分。点击 Virtualenv 部分的红色字体链接,填入并保存。
195198
196199
197200### 静态文件
198201
199- 静态文件可以交给 PythonAnywhere 设置的服务器来处理,这样会更高效 。要让 PythonAnywhere 处理静态文件,我们只需要在 Static files 部分指定静态文件 URL 和对应的静态文件文件夹目录,如下所示:
202+ 静态文件可以交给 PythonAnywhere 设置的 Web 服务器来处理,这样处理性能会更好 。要让 PythonAnywhere 处理静态文件,我们只需要在 Static files 部分指定静态文件 URL 和对应的静态文件文件夹目录,如下所示:
200203
201- ![ 静态文件配置] ( images/11-10 .png )
204+ ![ 静态文件配置] ( images/11-11 .png )
202205
203- 注意更新目录中的用户名和项目文件夹名称。
206+ Flask 程序的静态文件默认 URL 为“/static”,因此这里的 URL 填入“/static/”;对应的目录是程序包里的静态文件夹,比如“/home/greyli/watchlist/watchlist/static/”。 注意更新目录中的用户名和项目文件夹名称。
204207
205208
206209### 启动程序
207210
208- 一切就绪,点击绿色的重载按钮即可让配置生效 :
211+ 一切就绪,点击绿色的重载(Reload)按钮即可让配置生效 :
209212
210- ![ 重载程序] ( images/11-11 .png )
213+ ![ 重载程序] ( images/11-12 .png )
211214
212- 现在访问你的程序网址“< https://用户名.pythonanywhere.com > ”(Web 面板顶部的链接 ),比如 < https://greyli.pythonanywhere.com > 即可访问程序。
215+ 现在访问你的程序网址“< https://用户名.pythonanywhere.com > ”(可以在 Web 面板顶部找到链接 ),比如 < https://greyli.pythonanywhere.com > 即可访问程序。
213216
214217最后还要注意的是,免费账户需要每三个月点击一次黄色的激活按钮(在过期前你会收到提醒邮件):
215218
216- ![ 激活程序] ( images/11-12 .png )
219+ ![ 激活程序] ( images/11-13 .png )
217220
218221
219222## 更新部署后的程序
220223
221- 当你需要更新程序时,流程和部署类似。在本地完成更新,确保程序通过测试后,将代码推送到 GitHub 上的远程仓库。登录到 PythonAnywhere,打开一个命令行会话(Bash),切换到项目目录,使用 git pull 命令从远程仓库拉取更新:
224+ 当你需要更新程序时,流程和部署类似。在本地完成更新,确保程序通过测试后,将代码推送到 GitHub 上的远程仓库。然后登录到 PythonAnywhere,打开一个命令行会话(Bash),切换到项目目录,使用 git pull 命令从远程仓库拉取更新:
222225
223226``` bash
224227$ cd watchlist
@@ -232,7 +235,7 @@ $ git pull
232235
233236程序部署上线以后,你可以考虑继续为它开发新功能,也可以从零编写一个新的程序。虽然本书即将接近尾声,但你的学习之路才刚刚开始,因为本书只是介绍了 Flask 入门所需的基础知识,你还需要进一步学习。在后记中,你可以看到进一步学习的推荐读物。
234237
235- 接下来,有一个挑战在等着你 。
238+ 接下来,还有一个挑战在等着你 。
236239
237240
238241## 进阶提示
0 commit comments