Empaquetage pour la production — Déploiement sur Railway

Dans ce chapitre, vous apprendrez comment appliquer le patron de fabrique, configurer l'environnement de production et déployer le blog Flask en production à l'aide de Railway.


Modèle de fabrique d'application create_app()

Jusqu'à présent, app.py créait directementapp = Flask(__name__), ce qui est suffisant pour le développement, mais il y a plusieurs problèmes :

  • Impossible de créer une instance d'application indépendante pendant les tests
  • Impossible de basculer entre différentes configurations en fonction de l'environnement (développement/test/production)
  • L'initialisation des extensions est étroitement couplée à l'instance de l'application

Modèle de fabrique d'applicationCela résout ces problèmes : encapsuler la création de l'application dans une fonction.

Exemple

# Chemin du fichier : 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):
    """Fabrique d'application : crée une instance d'application Flask basée sur la classe de configuration"""
    app = Flask(__name__)
    app.config.from_object(config_class)

    # Initialiser les extensions (d'abord créer l'instance d'application, puis lier les extensions à l'application)
    db.init_app(app)
    login_manager.init_app(app)
    migrate.init_app(app, db)

    login_manager.login_view = 'auth.login'
    login_manager.login_message = 'Veuillez d'abord vous connecter avant d'accéder.'

    # Enregistrer le 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 doit être défini après que l'application existe
    from app.models import User
    @login_manager.user_loader
    def load_user(user_id):
        return User.query.get(int(user_id))

    return app

Fichier de configuration config.py

Exemple

# Chemin du fichier : config.py
import os
from dotenv import load_dotenv

# Charger les variables d'environnement depuis le fichier .env (uniquement pour l'environnement de développement)
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

# Sélectionner la configuration en fonction des variables d'environnement
config_map = {
    'development': DevelopmentConfig,
    'production': ProductionConfig,
    'default': DevelopmentConfig
}

Nouveau fichier d'entrée wsgi.py

Exemple

# Chemin du fichier : wsgi.py
from app import create_app

app = create_app()

Maintenant, la méthode de démarrage devient :

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

Notez l'ordre d'importation : Blueprint et user_loader doivent être importés à l'intérieur de create_app() (pas en haut du fichier), sinon des imports circulaires seront déclenchés (Blueprint référence models, models référence db, et db n'est pas encore lié à l'application à ce moment-là).


Générer requirements.txt et Procfile

(venv) $ pip freeze > requirements.txt

Assurez-vous que le fichier contient les dépendances clés : Flask, Flask-SQLAlchemy, Flask-Migrate, Flask-Login, Flask-WTF, Flask-Admin, gunicorn, python-dotenv.

Créer dans le répertoire racine du projetProcfile:

web: gunicorn wsgi:app

Poussez le projet vers 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

Assurez-vous de.envajoutez.gitignoreLe fichier .env contient des informations sensibles telles que SECRET_KEY. Une fois commité sur GitHub, il ne peut pas être complètement supprimé (l'historique Git le conservera).


Déploiement sur Railway

  1. Visitezrailway.app,connectez-vous avec GitHub
  2. Nouveau projet → Déployer depuis le dépôt GitHub → sélectionnez flask-blog
  3. Railway détecte automatiquement le Procfile et identifie la commande de démarrage Gunicorn
  4. Définissez les variables d'environnement dans Variables.
  5. Cliquez sur Deploy

Configuration des variables d'environnement

Nom de la variableValeurDescription
SECRET_KEYLongue chaîne générée aléatoirementChiffrer la session et le jeton CSRF
DATABASE_URLInjecté automatiquement par RailwayBase de données de production (PostgreSQL fourni par Railway)
FLASK_ENVproductionIdentifiant de l'environnement de production

Générer rapidement SECRET_KEY :

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

Après un déploiement réussi, obtenez un lien commehttps://flask-blog.up.railway.app。


Prochaine orientation d'apprentissage

Orientation d'apprentissagePour qui est-ce destinéPoint de départ recommandé
API REST FlaskCréer une API pour les frameworks front-end (Vue3/React)Utiliser jsonify au lieu de render_template pour créer des API RESTful
Séparation front-end et back-end avec Flask + Vue3/ReactVous voulez utiliser Flask pour le back-end et Vue3/React pour le front-endFlask fournit une API JSON, et le frontend communique via fetch
PostgreSQLBesoin d'une base de données de niveau productionRemplacer SQLite, installer psycopg2, modifier DATABASE_URL
Déploiement DockerDéploiement conteneuriséÉcrire un Dockerfile et orchestrer avec docker-compose
autres extensions