- Flask自带的开发服务器不适合用作生产环境。
部署流程
不论哪种托管方案,应用安装到生产服务器上之后都要执行一系列的任务,其中包括创建和更新数据库表。如果每次都手动操作会很麻烦,因此编写py程序来做这些工作。
from flask_migrate import upgrade
from app.models import User, Follow, Role, Permission, Post, Comment
from app import create_app, db
app = create_app()
@app.cli.command()
def deploy():
"""Run deployment tasks."""
# migrate database to latest revision
upgrade()
# create or update user roles
Role.insert_roles() # 初始化角色表中的角色
# ensure all users are following themselves
User.add_self_follows() # 关注模块:确保个体关注了自身
由于命令执行可能出错,所以在实现上面的函数的时候要考虑多次执行的情况,由于本身已经考虑了,所以这里如果deploy执行失败,多次执行不会有影响。
把生产环境中的错误写入日志
在dev环境下时Werkzeug是直接在shell里输出err_log和在网页显示错误信息。Prod环境不能对外展示错误,否则容易被黑客利用。这时候我们一般是进行错误重定向和写日志。应用启动时会创建logging.Logger的实例并附加在应用实例上通过app.logger访问。同时我们可以让错误日志发送到管理员的邮箱。
class ProductionConfig(Config):
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
'sqlite:///' + os.path.join(basedir, 'data.sqlite')
@classmethod
def init_app(cls, app):
Config.init_app(app)
# email errors to the administrators
import logging
from logging.handlers import SMTPHandler
credentials = None
secure = None
if getattr(cls, 'MAIL_USERNAME', None) is not None:
credentials = (cls.MAIL_USERNAME, cls.MAIL_PASSWORD)
if getattr(cls, 'MAIL_USE_TLS', None):
secure = ()
mail_handler = SMTPHandler(
mailhost=(cls.MAIL_SERVER, cls.MAIL_PORT),
fromaddr=cls.FLASKY_MAIL_SENDER,
toaddrs=[cls.FLASKY_ADMIN],
subject=cls.FLASKY_MAIL_SUBJECT_PREFIX + ' Application Error',
credentials=credentials,
secure=secure)
mail_handler.setLevel(logging.ERROR)
app.logger.addHandler(mail_handler)
Reference
- Flask 应用如何部署
- 《Flask Web开发:基于Python的web开发应用实践》
