Desplegar una webapp
Tema: Desplegar una webapp
Entradas:
Nov 21, 2025 15:07
Como decía Sir Terry Pratchett:
primero vives y luego pasas el resto de la vida intentando entender qué demonios ha pasado.
Primero he hecho esta web y ahora trato de entender qué demonios he hecho.
Esa es una de las razones por las que escribo esta entrada. La otra es que he cometido varios errores y puede ser interesante por si alguien se ve en la misma situación. No voy a entrar en todos los detalles técnicos porque el post se haría eterno; el objetivo es que tengas una visión general de cómo encajan las piezas y qué función tiene cada una.
Al final no existe la guía perfecta que cubra absolutamente todo. Para montar esto yo consulté el Python Crash Course, unos cuatro blogs distintos, la documentación oficial… y aun así la liaba. Así que aquí tienes una guía más, que puede ayudar a que las piezas vayan encajando cuando te pongas a desplegar tu webapp. Y, de paso, le voy a dar un enfoque de seguridad, que es el tema de este sitio.
La santísima trinidad de cualquier webapp en Django es: views, templates y urls. Yo lo entiendo así, con esta metáfora teatral: - Las views son las funcionalidades puras, lo que realmente hace cada actor, su papel. - Las templates son el escenario y el atrezo: cómo se presenta todo y cómo el usuario interactúa con esas funcionalidades. - Las urls son los caminos del teatro: las rutas que conectan unas partes con otras, como una escena que da paso a otra. - Y Django, como web framework, en su conjunto sería el propio teatro: el edificio y todas las herramientas que nos dan para montar la obra.
Aquí podemos ver un ejemplo de la función topic definida en view.py en el directorio de mi app, que se inicializa con un startapp de Django. En urls guiamos lo que veremos en la dirección URL con la función que, a su vez, nos lleva a la plantilla HTML de topic.
def topic(request, topic_id):
""" Show a single topic and all its entries """
topic = Topic.objects.get(id=topic_id)
entries = topic.entry_set.order_by('-date_added')
context = {'topic': topic, 'entries': entries}
return render(request, 'LogsApp/topic.html', context)
urlpatterns = [
path('topics/<int:topic_id>/', views.topic, name='topic'),
]
Hay otros 3 conceptos importantes: database, models y manage. Con manage damos órdenes a Django desde la terminal, como runserver o makemigrations. Cuando creamos un model, estamos definiendo una plantilla con la información que tendrá en la base de datos esa entidad.
cat models.py
from django.db import models
class Topic(models.Model):
text = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.text
Tendremos que crear la base de datos y conectarnos con nuestro usuario. Creo que por defecto Django inicializa con SQLite, pero es fácil cambiarse a PostgreSQL. En settings.py veremos la info de la base de datos, que podemos modificar, al igual que añadir nuestra app o la opción de DEBUG = True, que será importante desactivar luego.
Todo esto lo estamos haciendo en un entorno virtual, que me lo imagino como estas habitaciones de entrenamiento con simulación: no rompes las configuraciones y versiones de nuestro ordenador. Solo en tu simulación.
Supongamos que hemos probado nuestra web en localhost y va bien. Ahora queremos que el mundo la vea. Primero subimos el proyecto a GitHub. Podríamos hacer el repositorio público tomando ciertas medidas. Yo lo tengo en privado por tener una capa extra de seguridad. Lo fundamental es poner en .gitignore los archivos que no queremos subir, por ejemplo el .env, que almacena las variables de entorno donde tendremos la información sensible. Este es un extracto de mi settings donde uso el módulo dotenv (hay otros); por ejemplo la opción de DEBUG o los puertos también podrían estar en el .env.
from dotenv import load_dotenv
load_dotenv()
SECRET_KEY = os.getenv('SECRET_KEY')
DATABASE_URL = os.getenv('DATABASE_URL')
DEBUG = False
Bien, toca elegir VPS o web hosting. Yo lo hice por Hostinger y tomé la opción de VPS porque quería complicarme la vida. No sé cómo irá el web hosting, pero supongo que no tendrás que configurar nada del servidor. Y tienes mil características incluidas, por supuesto IA, para manejar tu web.
A nivel de seguridad, la principal diferencia es que en mi VPS manejo yo completamente su configuración: lo que entra y lo que sale. Un web hosting por lo general tiene un servidor “grande” con muchos negocios alojando su web. Entonces se me ocurre que si una de las webs recibe un ataque DDoS, el servidor tiene que enfocar sus recursos en mantenerla activa, quitando del tuyo. Si a través de otra web encuentran un vector de entrada y logran escalar privilegios dentro del servidor, podrían comprometerte a ti.
Al final no sabes qué medidas de seguridad está implementando esa empresa; simplemente confías en que lo harán bien.
https://evilcorporations.com/godaddy-ftc-data-breach-complaint/
Vaya, aquí hay un reporte de las negligencias en ciberseguridad de una de las empresas más grandes de web hosting, GoDaddy. Fallos como no tener MFA para los administradores, permitir el movimiento lateral en el servidor, falta de monitorización, etc.
Sería muy interesante analizar en detalle algunos de estos reportes; me lo apunto para el futuro porque me salen muchas preguntas: si tú te anuncias como un servicio súper seguro, ¿qué medidas mínimas (legales) debes tener? ¿Está regulado eso? ¿Cómo segmentan los servidores para no permitir el movimiento lateral del atacante?
Volvamos a nuestra guía. Si elegimos la VPS, en Hostinger nos darán a elegir un sistema operativo. Update & upgrade y listo: tienes tu IP y te hacen generar una clave SSH para que te puedas conectar desde tu PC.
Lo más seguro es que entres como root. Cámbialo. Añade un usuario que funcionará como administrador. Ese fue mi mayor error: entré como root, cloné el repositorio y me puse a desplegarlo. Esto es una cagada por dos motivos: la seguridad son capas; no queremos que, si me hackean, tengan ya permisos de root. Vamos a ponérselo un poco difícil, ¿no? Que al menos suden un poco.
El otro motivo es simplemente que, al usar Nginx y Gunicorn, tienen el usuario www-data. Tienes que darle permisos de grupo o como usuario para que puedan acceder a las carpetas y archivos.
Llegados a este punto, tendrás que adquirir un nombre de dominio y luego, en la tabla DNS, asociarlo a la IP que tiene tu servidor. Prueba a conectarte a la IP o al nuevo nombre; lo tendrás que especificar en settings → allowed hosts. Seguramente te saldrá un mensaje de Apache Debian, en mi caso, diciéndonos que hemos tenido éxito al conectarnos al servidor. Aquí es donde entran en juego Nginx y Gunicorn. ¿Qué son? ¿Y qué diferencia hay? ¿Por qué los necesito?
Nginx es un web server (aparte de load balancer y reverse proxy). Me falta estudiar más este tema, pero creo que funciona similar a un proxy server, es decir, un intermediario entre las peticiones de los usuarios y el servidor. Gestiona las requests, comprime y la encriptación SSL son algunas de sus ventajas. Si fuéramos una empresa más grande, con muchos servidores, es una forma de concentrar tus defensas en una sola puerta de entrada.
Pero Nginx por sí solo no nos sirve: tenemos que traducir las peticiones HTTP a algo que nuestra aplicación de Python pueda entender. Ahí entra en juego Gunicorn, que es un app server e implementa el estándar WSGI (Web Server Gateway Interface).
Este sería el esquema:
Usuario de internet → quiere ver un post → Nginx gestiona la petición, encripta, distribuye, etc. → Gunicorn traduce a Python → nuestra app en Django devuelve el resultado ←
De todas las herramientas que proporciona Nginx, solo he utilizado de momento la certificación SSL. Pero, echando un vistazo, veo que se pueden configurar las referrer-policy y content-security-policy del header, lo cual no sé qué significa o a qué afecta, pero me da curiosidad descubrirlo.
Y eso es todo, gente. Hay muchas cosas que quiero bichear de la web, como automatizar los posts, crear una mailbox, etc. Pero también estoy liado con los cursos de hacking. Seguramente el siguiente post sea de lo que he aprendido al hacer The Bandit, y luego quiero hablar del anonimato web.
¡Hasta luego!