Despliegue de Flask

Una vez completado el desarrollo, es necesario desplegar la aplicación Flask en el entorno de producción para que los usuarios reales puedan acceder a ella.

Este capítulo presenta los pasos clave y las consideraciones importantes desde el desarrollo hasta la producción.


Servidor de desarrollo vs servidor de producción

Importante: El servidor de desarrollo integrado de Flask (flask run) solo es adecuado para el entorno de desarrollo. No tiene la seguridad, estabilidad ni rendimiento necesarios para el entorno de producción. En producción se debe utilizar un servidor WSGI profesional.

Características Servidor de desarrollo Flask Servidor WSGI de producción (Gunicorn/Waitress)
Procesamiento concurrente Un solo hilo (por defecto) Multiproceso/multihilo/corutinas
Seguridad El modo Debug puede ejecutar código en el navegador Sin funciones de depuración, seguro y controlable
Rendimiento Sin optimizar Optimizado para alta concurrencia
Escenarios de aplicación Desarrollo local, depuración Entorno de producción en línea

Lista de verificación de despliegue

Antes de desplegar, asegúrate de que se hayan completado los siguientes puntos:

Ejemplo

# Ruta del archivo: app.py (verificación de configuración relacionada con el entorno de producción)
import os

app.config.update(
    # 1. Desactivar el modo Debug (¡obligatorio!)
    DEBUG=False,

    # 2. Leer la clave desde variables de entorno (nunca codificarla fija)
    SECRET_KEY=os.environ.get("FLASK_SECRET_KEY", ""),

    # 3. Configurar opciones de seguridad de las cookies de sesión
    SESSION_COOKIE_SECURE=True,   # Transmitir solo a través de HTTPS
    SESSION_COOKIE_HTTPONLY=True, # Prohibir el acceso de JavaScript
    SESSION_COOKIE_SAMESITE="Lax",  # Prevenir ataques CSRF
)

Lista de verificación completa:

Elemento de verificación Descripción Nivel de riesgo
DEBUG = False Desactivar el modo de depuración para evitar la filtración de código Crítico
SECRET_KEY aleatorio y confidencial Session y flash dependen de la firma con la clave Crítico
SECRET_KEY se lee desde variables de entorno No codificarlo, no enviarlo a Git Crítico
La contraseña de la base de datos se lee desde variables de entorno La información sensible no debe estar en el código Crítico
SESSION_COOKIE_SECURE = True Enviar cookies solo a través de HTTPS Alto
Las páginas de error no exponen la información de la pila Usar un errorhandler personalizado Medio

Despliegue con Waitress (Windows/macOS/Linux)

WaitressEs un servidor WSGI puro en Python, multiplataforma y de instalación sencilla:

(.venv) $ pip install waitress

Ejemplo

# Ruta del archivo: run.py (script de inicio en producción)
from waitress import serve
from app import create_app

app = create_app()

if __name__ == "__main__":
    # Iniciar el servidor de producción
    serve(app, host="0.0.0.0", port=8000, threads=4)
    # host="0.0.0.0" permite el acceso externo
    # threads=4 usa 4 hilos para manejar solicitudes concurrentes

Iniciar:

(.venv) $ python run.py
Serving on http://0.0.0.0:8000

Despliegue con Gunicorn (Linux/macOS)

GunicornEs el servidor WSGI de Python más popular en entornos Linux, con excelente rendimiento:

(.venv) $ pip install gunicorn

Iniciar Gunicorn (especificando la aplicación directamente en la línea de comandos):

# 基本用法:4 个 worker 进程
$ gunicorn -w 4 -b 0.0.0.0:8000 "app:create_app()"

# 参数说明:
# -w 4       : 启动 4 个 worker 进程(通常设为 CPU 核心数 × 2 + 1)
# -b 0.0.0.0:8000 : 监听所有网络接口的 8000 端口
# "app:create_app()" : 模块名:工厂函数(与 flask --app 语法相同)

Selección del tipo de worker de Gunicorn:

Tipo de worker Escenario de aplicación Comando
sync (por defecto) Intensivo en CPU, baja concurrencia gunicorn -w 4 app:app
gevent Intensivo en E/S, alta concurrencia y conexiones largas gunicorn -k gevent -w 4 app:app
gthread Concurrencia media, necesita soporte de hilos gunicorn --threads=2 -w 4 app:app

Gunicorn no es compatible con Windows. Si despliegas en Windows, utilizaWaitress。


Usando Nginx como proxy inverso

En el entorno de producción, normalmente se usa Nginx como proxy inverso delante del servidor WSGI:

  • Nginx maneja archivos estáticos (CSS, JS, imágenes), con una eficiencia mucho mayor que Python
  • Nginx proporciona la terminación HTTPS (terminación SSL)
  • Nginx realiza equilibrio de carga, distribuyendo las solicitudes a varios workers backend

Flask 生产环境部署架构

Un ejemplo de configuración mínima de Nginx:

Ejemplo

# Ruta del archivo: /etc/nginx/sites-available/ejemplo
server {
    listen 80;
    server_name example.com www.example.com;

    # Los archivos estáticos son manejados directamente por Nginx
    location /static/ {
        alias /var/www/ejemplo/static/;
        expires 30d;  # El navegador almacena en caché durante 30 días
    }

    # Las demás solicitudes se reenvían a Gunicorn
    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Activar la configuración y recargar Nginx:

$ sudo ln -s /etc/nginx/sites-available/ejemplo /etc/nginx/sites-enabled/
$ sudo nginx -t          # 检查配置语法
$ sudo systemctl reload nginx

Gestionar servicios con systemd (Linux)

Crea un archivo de servicio systemd para que la aplicación Flask se inicie automáticamente al arrancar y se reinicie automáticamente tras un fallo:

Ejemplo

# Ruta del archivo: /etc/systemd/system/ejemplo.service
[Unit]
Description=EJEMPLO Flask Application
After=network.target

[Service]
User=www-data
WorkingDirectory=/var/www/ejemplo
# Cargar automáticamente las variables de entorno del archivo .env al iniciar
EnvironmentFile=-/var/www/ejemplo/.env
# Iniciar la aplicación usando Gunicorn
ExecStart=/var/www/ejemplo/.venv/bin/gunicorn -w 4 -b 127.0.0.1:8000 "app:create_app()"
# Reiniciar automáticamente después de un fallo
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Iniciar y gestionar el servicio:

$ sudo systemctl daemon-reload        # 重载配置文件
$ sudo systemctl enable ejemplo        # 设置开机自启
$ sudo systemctl start ejemplo         # 启动服务
$ sudo systemctl status ejemplo        # 查看服务状态
$ sudo journalctl -u ejemplo -f        # 实时查看日志

Referencia rápida de servidores WSGI

Servidor Plataforma Características Instalación
Werkzeug (integrado) Todas las plataformas Solo para desarrollo, admite recarga en caliente y depurador Incluido con Flask
Waitress Todas las plataformas Puro Python, la elección preferida en Windows pip install waitress
Gunicorn Linux/macOS Buen rendimiento, la elección preferida en Linux, ecosistema maduro pip install gunicorn
uWSGI Linux/macOS Funciones completas, configuración más compleja pip install uwsgi

Resumen del tutorial

¡Felicidades, has completado todo el contenido del tutorial introductorio de Flask!

Repasemos lo que has aprendido:

Capítulo Habilidades clave
Conocer Flask Entender el posicionamiento y el ecosistema de Flask
Preparación del entorno Crear un entorno virtual, instalar dependencias
Primera aplicación Crear una aplicación mínima, usar flask run
Sistema de rutas Mapeo de URLs, reglas de variables, url_for, métodos HTTP
Solicitudes y respuestas Leer datos de la solicitud, construir varios tipos de respuestas
Renderizado de plantillas Sintaxis de Jinja2, herencia de plantillas, protección XSS
Archivos estáticos Gestionar recursos estáticos como CSS/JS/imágenes
Session y Cookie Mantenimiento del estado del usuario, mensajes flash
Gestión de configuración Configuración multi-entorno, carga de variables de entorno
Blueprint (plano) Organización modular del código, patrón de fábrica
Manejo de errores Páginas de error personalizadas, registro de logs
Integración de bases de datos Operaciones con SQLite, gestionar conexiones con el objeto g
Pruebas test_client, pytest para probar rutas y API
Despliegue Gunicorn/Waitress + Nginx + systemd

Direcciones recomendadas para continuar aprendiendo:

  • Flask-SQLAlchemy: Integración de bases de datos más potente
  • Flask-Login: Autenticación y gestión de permisos de usuarios
  • Flask-WTF: Procesamiento de formularios y protección CSRF
  • Flask-Migrate: Gestión de migraciones de bases de datos
  • Flask-RESTfuloFlask-RESTX: Construir APIs RESTful
  • DockerDespliegue con contenedores, para mejorar aún más la portabilidad
Otras extensiones