现在位置: 首页 > Flask 教程 > 正文

打包上线 — 部署到 Railway

本章你将学会应用工厂模式、生产环境配置,并用 Railway 将 Flask 博客部署上线。


应用工厂模式 create_app()

到目前为止,app.py 中直接创建了 app = Flask(__name__),这在开发时够用,但有几个问题:

  • 测试时无法创建独立的 app 实例
  • 无法按环境(开发/测试/生产)切换不同配置
  • 扩展初始化与 app 实例紧耦合

应用工厂模式 解决了这些问题:把 app 的创建封装到一个函数中。

实例

# 文件路径:app/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from flask_migrate import Migrate
from config import Config

db = SQLAlchemy()
login_manager = LoginManager()
migrate = Migrate()

def create_app(config_class=Config):
    """应用工厂:根据配置类创建 Flask 应用实例"""
    app = Flask(__name__)
    app.config.from_object(config_class)

    # 初始化扩展(先创建 app 实例,再将扩展绑定到 app)
    db.init_app(app)
    login_manager.init_app(app)
    migrate.init_app(app, db)

    login_manager.login_view = 'auth.login'
    login_manager.login_message = '请先登录后再访问。'

    # 注册 Blueprint
    from app.blueprints.main import main_bp
    from app.blueprints.posts import posts_bp
    from app.blueprints.auth import auth_bp
    from app.blueprints.user import user_bp
    app.register_blueprint(main_bp)
    app.register_blueprint(posts_bp)
    app.register_blueprint(auth_bp)
    app.register_blueprint(user_bp)

    # user_loader 需要在 app 存在后定义
    from app.models import User
    @login_manager.user_loader
    def load_user(user_id):
        return User.query.get(int(user_id))

    return app

配置文件 config.py

实例

# 文件路径:config.py
import os
from dotenv import load_dotenv

# 从 .env 文件加载环境变量(仅开发环境使用)
load_dotenv()

class Config:
    SECRET_KEY = os.environ.get('SECRET_KEY', 'dev-secret-key')
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL', 'sqlite:///blog.db')
    SQLALCHEMY_TRACK_MODIFICATIONS = False

class DevelopmentConfig(Config):
    DEBUG = True

class ProductionConfig(Config):
    DEBUG = False

# 根据环境变量选择配置
config_map = {
    'development': DevelopmentConfig,
    'production': ProductionConfig,
    'default': DevelopmentConfig
}

新的入口文件 wsgi.py

实例

# 文件路径:wsgi.py
from app import create_app

app = create_app()

现在启动方式变为:

(venv) $ flask --app wsgi run --debug      # 开发模式
(venv) $ gunicorn wsgi:app                  # 生产模式(Gunicorn)

注意 import 顺序:Blueprint 和 user_loader 必须在 create_app() 内部导入(而非文件顶部),否则会触发循环导入(Blueprint 引用了 models,models 引用了 db,而 db 此时尚未绑定到 app)。


生成 requirements.txt 与 Procfile

(venv) $ pip freeze > requirements.txt

确保文件中包含关键依赖:Flask、Flask-SQLAlchemy、Flask-Migrate、Flask-Login、Flask-WTF、Flask-Admin、gunicorn、python-dotenv。

在项目根目录创建 Procfile

web: gunicorn wsgi:app

将项目推送到 GitHub

$ git init
$ echo "venv/" > .gitignore
$ echo "__pycache__/" >> .gitignore
$ echo "*.pyc" >> .gitignore
$ echo "instance/" >> .gitignore
$ echo ".env" >> .gitignore
$ git add .
$ git commit -m "初始化 Flask 博客项目"
$ git branch -M main
$ git remote add origin https://github.com/你的用户名/flask-blog.git
$ git push -u origin main

务必把 .env 加入 .gitignore。.env 文件包含 SECRET_KEY 等敏感信息,一旦提交到 GitHub 就无法彻底删除(Git 历史会保留)。


Railway 部署

  1. 访问 railway.app,用 GitHub 登录
  2. New Project → Deploy from GitHub repo → 选择 flask-blog
  3. Railway 自动检测 Procfile,识别 Gunicorn 启动命令
  4. 在 Variables 中设置环境变量
  5. 点击 Deploy

环境变量配置

变量名说明
SECRET_KEY随机生成的长字符串加密 Session 和 CSRF Token
DATABASE_URL由 Railway 自动注入生产数据库(Railway 提供 PostgreSQL)
FLASK_ENVproduction生产环境标识

快速生成 SECRET_KEY:

$ python -c "import secrets; print(secrets.token_urlsafe(50))"

部署成功后,获得链接如 https://flask-blog.up.railway.app


下一步学习方向

学习方向适合谁推荐起点
Flask REST API为前端框架(Vue3/React)构建 API用 jsonify 代替 render_template,构建 RESTful 接口
Flask + Vue3/React 前后端分离想用 Flask 做后端,Vue3/React 做前端Flask 提供 JSON API,前端 fetch 通信
PostgreSQL需要生产级数据库替换 SQLite,安装 psycopg2,修改 DATABASE_URL
Docker 部署容器化部署编写 Dockerfile,用 docker-compose 编排