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
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
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
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
- Visitarailway.app, inicia sesión con GitHub
- New Project → Deploy from GitHub repo → selecciona flask-blog
- Railway detecta automáticamente el Procfile y reconoce el comando de inicio de Gunicorn
- Configura las variables de entorno en Variables
- Haz clic en Deploy
Configuración de variables de entorno
| Nombre de la variable | Valor | Descripción |
|---|---|---|
| SECRET_KEY | Cadena larga generada aleatoriamente | Cifra la sesión y el token CSRF |
| DATABASE_URL | Inyectado automáticamente por Railway | Base de datos de producción (Railway proporciona PostgreSQL) |
| FLASK_ENV | production | Indicador 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 aprendizaje | Para quién | Punto de partida recomendado |
|---|---|---|
| Flask REST API | Crear 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/React | Quieres usar Flask como backend y Vue3/React como frontend | Flask proporciona una API JSON, el frontend se comunica con fetch |
| PostgreSQL | Necesitas una base de datos a nivel de producción | Reemplaza SQLite, instala psycopg2 y modifica DATABASE_URL |
| Despliegue con Docker | Despliegue mediante contenedores | Escribe el Dockerfile y usa docker-compose para la orquestación |