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
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
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
Un ejemplo de configuración mínima de Nginx:
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
[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