De una aplicación Django a un sitio estático
Esta web comenzó como una aplicación Django tradicional. Django sigue siendo la herramienta con la que gestiono el contenido y genero el sitio, pero la versión publicada no necesita ejecutar Python ni una base de datos en producción.
La decisión fue generar una versión estática de la web y publicarla directamente en el servidor. De esta forma, en producción solo se sirven HTML, CSS, JavaScript e imágenes, manteniendo la sencillez del alojamiento y eliminando la necesidad de ejecutar un servidor de aplicaciones.
Arquitectura
Django
│
├── Modelos y contenidos
├── Django Admin
└── Templates
│
▼
Generador estático
scripts/build_static.py
│
▼
dist/
│
▼
GitHub Actions
│
▼
FTPS
│
▼
Mi proveedor de alojamiento
│
▼
www.jlguerra.es
Generación del sitio
El proceso de construcción utiliza el propio proyecto Django para renderizar las páginas públicas. El script genera la estructura estática, adapta los enlaces para que funcionen desde cada directorio, recopila los archivos estáticos y copia las imágenes y demás contenidos necesarios.
El resultado incluye las páginas públicas, robots.txt, sitemap.xml, los archivos estáticos y los recursos multimedia.
Los contenidos no dependen de la base de datos publicada
La base de datos SQLite que utilizo durante el desarrollo no forma parte del repositorio ni del despliegue. El contenido que necesita el proyecto se puede reconstruir mediante las migraciones de Django y un fixture versionado en json.
Esto permite que el entorno de CI pueda crear una base de datos limpia, aplicar las migraciones, cargar el contenido y generar la web sin depender de mi base de datos local.
Control de versiones y despliegue
Aprovechando que el control de versiones del proyecto se gestiona con Git y el repositorio se aloja en GitHub, el propio historial de cambios sirve como punto de partida para el proceso de publicación.
El despliegue automático está deliberadamente protegido: hacer un push a la rama de despliegue no publica la web por sí solo. Para que GitHub Actions publique automáticamente, el mensaje del commit debe comenzar con un prefijo específico que actúa como autorización explícita para publicar.
Esto permite realizar cambios, pruebas y commits de desarrollo sin provocar una publicación accidental. Este mecanismo funciona como una confirmación explícita de que ese commit está preparado para llegar a producción.
git push
│
├── commit normal
│ │
│ └── no se publica
│
└── commit "my_prefix: ..."
│
▼
GitHub Actions
│
├── Django checks
├── Migraciones
├── Fixture
├── Tests
└── Build estático
│
▼
FTPS
│
▼
Mi proveedor de alojamiento
También es posible lanzar el workflow manualmente desde GitHub Actions. En ambos casos, antes de publicar se ejecutan las comprobaciones, migraciones, carga del contenido, tests y generación del sitio estático. Si todo es correcto, la web estática generada se publica mediante FTPS.
¿Por qué hacerlo así?
Porque la web no necesita funcionalidades dinámicas en producción. Django aporta una forma cómoda de estructurar el proyecto, gestionar los contenidos y reutilizar templates, mientras que el sitio estático permite publicar el resultado de una forma sencilla, rápida y con muy pocos requisitos en el servidor.
El proyecto es, en sí mismo, una pequeña muestra de una idea que aplico también en otros desarrollos: elegir la arquitectura en función de las necesidades reales del problema, en lugar de añadir complejidad que no aporta valor.