Flask 入门与部署

这篇把 Flask 的入门要点和上线部署合在一处:先是常用的扩展模块、开发期的调试模式和两类上下文变量,再是把应用交付到生产环境的几种方式,重点是用 Docker 与 Compose 编排容器。

1. 常用模块

Flask 本身只是一个很薄的核心——路由、调试和 WSGI(Web 服务器网关接口)子系统由 Werkzeug 提供,模板系统由 Jinja2 提供。剩下的能力都靠扩展按需装配:

  1. pipenv:虚拟环境管理,把项目依赖和系统 Python 隔开
  2. flask:主体框架,包含路由、调试器与开发服务器
  3. flask-wtf:对独立的 WTForms 包做了封装,用于表单处理与 CSRF 校验
  4. flask-sqlalchemy:数据库框架,简化在 Flask 应用中使用 SQLAlchemy;ORM 也可以换成别的
  5. flask-migrate:数据库迁移框架,配合 SQLAlchemy 管理表结构变更
  6. flask-mail:电子邮件支持
  7. flask-login:管理用户身份验证的登录状态,且不绑定特定的验证机制

2. 调试模式

Flask 应用在调试模式下运行时,默认会加载重载器调试器

  • 重载器:源码文件变动时自动重启服务器,改完代码不用手动重启
  • 调试器:应用抛出未处理的异常时,浏览器里会直接显示交互式的错误堆栈

开启方式是设置环境变量后再启动:

1
2
3
export FLASK_APP=app.py
export FLASK_DEBUG=1
flask run

千万不要在生产服务器上启动调试模式。浏览器里的调试器允许在服务器进程中执行任意代码,即便它要求先输入 PIN,也绝不能暴露到公网。

3. 应用和请求上下文

Flask 把几个常用对象做成了上下文全局变量,用起来像全局变量,实际上按上下文隔离,不会串。

变量名 上下文 说明
current_app 应用上下文 当前应用的应用实例
g 应用上下文 处理请求时用作临时存储的对象,每次请求都会重设这个变量
request 请求上下文 请求对象,封装了客户端发出的 HTTP 请求中的内容
session 请求上下文 用户会话,值为一个字典,存储请求之间需要”记住”的值

请求上下文只在处理请求期间存在,因此在脚本或后台任务里直接访问 request 会报错,需要自己推入相应的上下文。

4. 部署

4.1 部署原则

  1. 把全部任务自动化,让部署可以重复执行而不依赖手工操作
  2. 把生产环境中的错误写入日志,而不是显示给用户

4.2 部署方式

  1. 云托管:自己在云主机上装环境、跑服务
  2. 容器:例如 Docker,把应用和依赖打成镜像
  3. PaaS:平台即服务,只交代码,运行环境由平台负责

4.3 用 Docker 部署

大致流程是四步:

  1. 安装 Docker
  2. 构建容器映像(写 Dockerfile,把应用和依赖装进镜像)
  3. 运行容器
  4. 数据库等有状态服务最好另开容器,不要和应用挤在一起
1
2
3
4
5
# 构建镜像
docker build -t myflask:latest .

# 运行容器,把宿主机 8000 端口映射到容器的 5000
docker run -d -p 8000:5000 --name myflask myflask:latest

容器多起来之后就该用容器编排了。把应用、数据库、缓存各自的镜像、端口、卷和依赖关系写进 docker-compose.yml,定义好的所有容器就可以用一条命令全部启动:

1
docker-compose up -d