Flask es un microframework de Python. Es simple, poderoso y te permite tener una aplicación web funcional rápidamente—en menos de una hora, para ser precisos. Escribes rutas, conectas una base de datos y despliegas. Aquí está la cuestión: Flask no impone una estructura de carpetas específica ni utiliza un ORM. Se trata de funciones de Python que devuelven HTML o JSON. Esta guía te ayudará a crear un gestor de tareas minimalista, con base de datos incluida.
Foto: Christopher Gower en Unsplash
Para quién es esto: Fundadores solitarios que crean MVPs, desarrolladores que quieren ciclos rápidos sin la carga de Django, o cualquier persona que busque herramientas internas en un VPS de Linux sin los dolores de cabeza de serverless.
Paso 1: Instalar Flask y Configurar Tu Proyecto
Primero, crea un directorio y configura un entorno virtual de Python. Flask no dicta la estructura, pero la aislamiento es crucial.
mkdir flask-taskapp && cd flask-taskapp
python3 -m venv venv
source venv/bin/activate # En Windows: venv\Scripts\activate
pip install Flask
Crea app.py en la raíz:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "Aplicación de tareas en funcionamiento"
if __name__ == '__main__':
app.run(debug=True)
Ejecuta:
python app.py
Visita http://127.0.0.1:5000/ en tu navegador. Deberías ver "Aplicación de tareas en funcionamiento." Ese es tu servidor web—un archivo, cero configuración.
Cabe destacar que Flask utiliza Werkzeug para WSGI y Jinja2 para plantillas. La documentación oficial de Flask es completa, mantenida por el equipo de Pallets y liderada por Armin Ronacher desde 2010.
Paso 2: Agregar una Base de Datos con SQLite y Flask-SQLAlchemy
Foto: Lee Campbell en Unsplash
Muchas aplicaciones de solopreneurs comienzan con SQLite. Es solo un archivo único—sin demonios, sin puertos. La migración siempre es una opción si es necesario.
Instala Flask-SQLAlchemy:
pip install Flask-SQLAlchemy
Actualiza app.py:
from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///tasks.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Task(db.Model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.String(200), nullable=False)
completed = db.Column(db.Boolean, default=False)
with app.app_context():
db.create_all()
@app.route('/')
def index():
tasks = Task.query.all()
return render_template('index.html', tasks=tasks)
@app.route('/add', methods=['POST'])
def add_task():
content = request.form.get('content')
if content:
new_task = Task(content=content)
db.session.add(new_task)
db.session.commit()
return redirect(url_for('index'))
@app.route('/delete/<int:task_id>')
def delete_task(task_id):
task = Task.query.get_or_404(task_id)
db.session.delete(task)
db.session.commit()
return redirect(url_for('index'))
if __name__ == '__main__':
app.run(debug=True)
Esto es lo que sucede: se define un modelo Task con campos id, content y completed. db.create_all() crea el archivo SQLite en la primera ejecución. Las rutas manejan la lista de tareas, la adición de nuevas y la eliminación por ID.
SQLAlchemy abstrae SQL, aunque las consultas en bruto son posibles para rendimiento. En la práctica, el ORM es suficiente para aplicaciones solitarias con menos de 10,000 filas.
Paso 3: Construir Plantillas con Jinja2
Flask emplea Jinja2 para la creación de plantillas. Crea una carpeta templates en la raíz de tu proyecto y agrega index.html:
mkdir templates
templates/index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gestor de Tareas</title>
<style>
body { font-family: sans-serif; max-width: 600px; margin: 50px auto; }
input[type="text"] { width: 70%; padding: 8px; }
button { padding: 8px 16px; }
ul { list-style: none; padding: 0; }
li { padding: 10px; border-bottom: 1px solid #ddd; }
a { color: red; text-decoration: none; margin-left: 10px; }
</style>
</head>
<body>
<h1>Tareas</h1>
<form action="/add" method="POST">
<input type="text" name="content" placeholder="Nueva tarea" required>
<button type="submit">Agregar</button>
</form>
<ul>
{% for task in tasks %}
<li>
{{ task.content }}
<a href="/delete/{{ task.id }}">Eliminar</a>
</li>
{% endfor %}
</ul>
</body>
</html>
Reinicia python app.py y recarga tu navegador. Ahora tienes un gestor de tareas con capacidades de agregar y eliminar. Jinja2 utiliza {% %} para lógica, {{ }} para salida.
Las plantillas están en templates/ porque Flask lo establece como predeterminado. Honestamente, para el 90% de los proyectos de un solo desarrollador, el predeterminado es más que suficiente.
Paso 4: Agregar Configuración de Entorno y Secretos
Codificar URIs de base de datos y claves secretas rompe el despliegue. Usa variables de entorno y un archivo .env.
Instala python-dotenv:
pip install python-dotenv
Crea .env en la raíz del proyecto:
SECRET_KEY=tu-clave-secreta-aleatoria-aquí
DATABASE_URI=sqlite:///tasks.db
Actualiza app.py:
import os
from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from dotenv import load_dotenv
load_dotenv()
app = Flask(__name__)
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY')
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URI')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Task(db.Model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.String(200), nullable=False)
completed = db.Column(db.Boolean, default=False)
with app.app_context():
db.create_all()
@app.route('/')
def index():
tasks = Task.query.all()
return render_template('index.html', tasks=tasks)
@app.route('/add', methods=['POST'])
def add_task():
content = request.form.get('content')
if content:
new_task = Task(content=content)
db.session.add(new_task)
db.session.commit()
return redirect(url_for('index'))
@app.route('/delete/<int:task_id>')
def delete_task(task_id):
task = Task.query.get_or_404(task_id)
db.session.delete(task)
db.session.commit()
return redirect(url_for('index'))
if __name__ == '__main__':
app.run(debug=True)
Agrega .env a .gitignore para evitar comprometer secretos:
echo ".env" >> .gitignore
En servidores de producción, establece las variables de entorno directamente. La mayoría de las plataformas (Heroku, Render, DigitalOcean App Platform) ofrecen configuración de entorno en sus paneles. Recuerda, nunca comprometas .env en el control de versiones.
Paso 5: Desplegar en un Servidor de Producción
El servidor de Flask no es para producción—es de un solo hilo y lento. Usa Gunicorn como tu servidor WSGI.
Instala Gunicorn:
pip install gunicorn
Crea requirements.txt:
pip freeze > requirements.txt
Tu requirements.txt debería listar:
Flask==3.0.0
Flask-SQLAlchemy==3.1.1
gunicorn==21.2.0
python-dotenv==1.0.0
Prueba localmente con Gunicorn:
gunicorn app:app
Esto ejecuta un servidor listo para producción en http://127.0.0.1:8000. El formato module:variable—app es tu archivo, el segundo app es la instancia de Flask.
Para el despliegue, los droplets de DigitalOcean funcionan bien con un VPS de $6/mes. Conéctate por SSH, clona tu repositorio, instala dependencias y ejecuta Gunicorn detrás de Nginx. La guía de despliegue de Flask de DigitalOcean cubre la configuración completa.
¿Prefieres plataformas sobre servidores? Render y Railway detectan automáticamente aplicaciones Flask y despliegan desde un push de GitHub. Ambas ofrecen niveles gratuitos suficientes para MVPs con menos de 1,000 usuarios diarios.
Lo Que Nadie Te Dice Sobre Flask
Flask no escala tu código—tú lo haces. Es minimalista por diseño. Tú agregas gestión de sesiones, autenticación de usuarios, trabajos en segundo plano y versionado de API. Django ofrece todo eso; Flask no ofrece nada, hasta que se incorporan extensiones.
¿Te preguntas sobre cómo organizar el código? Los blueprints son la respuesta de Flask. Si app.py supera las 300 líneas, divide las rutas en blueprints. La mayoría de los desarrolladores solitarios se las arreglan bien con un archivo durante meses—no lo pienses demasiado.
SQLite tiene problemas con escrituras concurrentes. Si estás construyendo un SaaS multiusuario que espera muchas escrituras, cambia a PostgreSQL temprano. Flask-SQLAlchemy lo convierte en un cambio de configuración, pero los patrones SQL pueden no traducirse. Prueba las consultas en Postgres en Docker local primero.
Para la gestión de sesiones, usa Redis o Flask-Session para sesiones del lado del servidor. ¿Construyendo algo con inicios de sesión? Instala Flask-Login. Crear una capa de sesión personalizada es un error común.
El manejo de errores en producción es silencioso por defecto. Usa Sentry o similar para capturar excepciones. El modo de depuración de Flask muestra trazas de pila localmente—nunca lo uses en producción.
Preguntas Frecuentes
¿Es Flask más rápido que Django?
Flask no es inherentemente más rápido—ambos son aplicaciones WSGI detrás de servidores similares (Gunicorn, uWSGI). Pero Flask tiene menos sobrecarga de inicio, ya que no carga el ORM de Django, el panel de administración o la pila de middleware. Una vez que las extensiones se acumulan, la brecha de rendimiento se estrecha. Elige Flask para control de dependencias; elige Django para un paquete todo en uno.
¿Puede Flask manejar miles de usuarios?
Sí, con la configuración adecuada. Instagram funcionó en Flask antes de la adquisición de Facebook. Por lo general, la base de datos es tu cuello de botella, no Flask. Usa agrupamiento de conexiones, optimización de consultas y caché de Redis. Escala horizontalmente desplegando detrás de un balanceador de carga con múltiples trabajadores de Gunicorn. Recuerda, Flask es sin estado.
¿Necesito Docker para el despliegue de Flask?
No, pero ayuda a la consistencia. ¿Desplegando en un VPS? Instala Python y dependencias directamente. Plataformas como Render o Fly.io gestionan contenedores por ti. Docker es útil para múltiples servicios (Flask + Celery + Redis) o para igualar entornos de desarrollo y producción. Para MVPs solitarios, un requirements.txt y un archivo de servicio systemd son suficientes.
¿Cuál es la mejor base de datos para Flask?
Comienza con SQLite para proyectos de menos de 10,000 filas. Cambia a PostgreSQL para escrituras concurrentes, búsqueda de texto completo o consultas JSON. Flask-SQLAlchemy admite ambos con cambios mínimos en la configuración. Evita MySQL a menos que haya una necesidad específica—Postgres ofrece mejor soporte para JSON y menos errores.
Conclusión
Flask es la forma más rápida de pasar de la idea a una aplicación web en vivo si conoces Python. Menos código que Django, control total sobre las dependencias y desplegable en cualquier servidor Linux. ¿Nunca has lanzado una aplicación web en solitario? Construye este gestor de tareas, despliega en un VPS de $6 y comparte el enlace con un amigo. Ese es tu primer producto real.
Próximo paso: agrega autenticación de usuario con Flask-Login y despliega en el nivel gratuito de Render. Tendrás una aplicación multiusuario lista en menos de dos horas. Para más información sobre herramientas de marketing por correo electrónico para solopreneurs, consulta nuestro artículo sobre las Mejores Herramientas de Marketing por Correo Electrónico para Solopreneurs en 2026. Si estás interesado en configurar Mailchimp para tus proyectos, nuestra guía sobre Configuración Paso a Paso de Mailchimp para Fundadores Solitarios puede ayudarte a comenzar.
Nota editorial: Este artículo fue elaborado con asistencia de IA y revisado por Javier Valencia. A lo largo del texto se distinguen los hechos verificados de la opinión editorial. Las fuentes externas enlazadas son independientes de NewsTide.