Empaquetado y lanzamiento — Despliegue en Railway

En este capítulo aprenderás el patrón de fábrica de aplicaciones, la configuración de producción y a desplegar el blog Flask en línea con Railway.


Patrón de fábrica de aplicaciones create_app()

Hasta ahora, en app.py se ha creado directamenteapp = Flask(__name__), esto es suficiente para el desarrollo, pero tiene varios problemas:

  • No se puede crear una instancia de app independiente durante las pruebas
  • No se puede cambiar a diferentes configuraciones según el entorno (desarrollo/pruebas/producción)
  • La inicialización de extensiones está estrechamente acoplada a la instancia de app

Patrón de fábrica de aplicacionesResuelve estos problemas: encapsula la creación de la app en una función.

Ejemplo

# Ruta del archivo: 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):
    """Fábrica de aplicaciones: crea una instancia de la aplicación Flask según la clase de configuración"""
    app = Flask(__name__)
    app.config.from_object(config_class)

    # Inicializar extensiones (primero crear la instancia de la app, luego vincular las extensiones a 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 = 'Por favor, inicia sesión para acceder.'

    # Registrar 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 debe definirse después de que exista la app
    from app.models import User
    @login_manager.user_loader
    def load_user(user_id):
        return User.query.get(int(user_id))

    return app

Archivo de configuración config.py

Ejemplo

# Ruta del archivo: config.py
import os
from dotenv import load_dotenv

# Cargar variables de entorno desde el archivo .env (solo para el entorno de desarrollo)
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

# Seleccionar la configuración según las variables de entorno
config_map = {
    'development': DevelopmentConfig,
    'production': ProductionConfig,
    'default': DevelopmentConfig
}

Nuevo archivo de entrada wsgi.py

Ejemplo

# Ruta del archivo: wsgi.py
from app import create_app

app = create_app()

Ahora la forma de iniciar cambia a:

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

Nota sobre el orden de importación: Blueprint y user_loader deben importarse dentro de create_app() (no al principio del archivo); de lo contrario, se provocará una importación circular (Blueprint hace referencia a models, models hace referencia a db, y db aún no está vinculado a app en ese momento).


Generar requirements.txt y Procfile

(venv) $ pip freeze > requirements.txt

Asegúrate de que el archivo contenga las dependencias clave: Flask, Flask-SQLAlchemy, Flask-Migrate, Flask-Login, Flask-WTF, Flask-Admin, gunicorn, python-dotenv.

En el directorio raíz del proyecto, creaProcfile:

web: gunicorn wsgi:app

Enviar el proyecto a 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

Asegúrate de.envagregar.gitignore. El archivo .env contiene información sensible como SECRET_KEY. Una vez enviado a GitHub, no se puede eliminar por completo (el historial de Git lo conserva).


Despliegue en Railway

  1. Visitarailway.app, inicia sesión con GitHub
  2. New Project → Deploy from GitHub repo → selecciona flask-blog
  3. Railway detecta automáticamente el Procfile y reconoce el comando de inicio de Gunicorn
  4. Configura las variables de entorno en Variables
  5. Haz clic en Deploy

Configuración de variables de entorno

Nombre de la variableValorDescripción
SECRET_KEYCadena larga generada aleatoriamenteCifra la sesión y el token CSRF
DATABASE_URLInyectado automáticamente por RailwayBase de datos de producción (Railway proporciona PostgreSQL)
FLASK_ENVproductionIndicador de entorno de producción

Genera rápidamente SECRET_KEY:

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

Después de un despliegue exitoso, obtendrás un enlace comohttps://flask-blog.up.railway.app。


Próximos pasos de aprendizaje

Ruta de aprendizajePara quiénPunto de partida recomendado
Flask REST APICrear una API para frameworks frontend (Vue3/React)Usa jsonify en lugar de render_template para construir interfaces RESTful
Separación de frontend y backend con Flask + Vue3/ReactQuieres usar Flask como backend y Vue3/React como frontendFlask proporciona una API JSON, el frontend se comunica con fetch
PostgreSQLNecesitas una base de datos a nivel de producciónReemplaza SQLite, instala psycopg2 y modifica DATABASE_URL
Despliegue con DockerDespliegue mediante contenedoresEscribe el Dockerfile y usa docker-compose para la orquestación
Otras extensiones