It begins - decisiones de diseño y hosting del blog

Todos tenemos nuestras tradiciones.

Como developer, empiezo todos mis proyectos con un “Hello world”, de ahí que la primera entrada sea tan pequeña. Como persona, como jdgomez, todos mis proyectos continúan con “It begins (don’t cry)”, así que aquí está la segunda entrada del blog.

Contexto

Como mucha gente, compré una Raspberry Pi hace tiempo y descubrí lo buena que era acumulando polvo. Hace poco recordé por qué la compré (sí, para alojar mi propio blog), por qué me hice developer, y decidí retomar ese proyecto como excusa para aprender qué puede hacer la IA por mí.

Por qué este stack

“No. I mean, I’m not a shop boy. I was just working in a shop.” - Tristan Thorn 1

Empecé a aprender a programar con C++ y os aseguro que lo echo mucho de menos. Ahora mismo estoy centrado en aprender Go y Python. Así que mi primera decisión fue programar mi propio servidor web. Lo haría en Go, y serviría como un gran ejercicio.

Por suerte para mí, uno de mis objetivos actuales es aprender más sobre IA, y al contrastar mi plan con Claude Code descubrí que… esa rueda ya estaba inventada.

Disclaimer: me encanta reinventar ruedas (quizás tema para otra entrada).

Hugo es un framework realmente rápido y ligero para construir sitios web. Está escrito en Go y puede generar HTML a partir de archivos Markdown. Me gusta Markdown como estándar para documentación y archivos limpios, no quiero lidiar con HTML ni CSS.
Normalmente no me gusta usar software en versiones alpha, y Hugo está ahora mismo en v0.161.1. Pero este proyecto también va de aprender, y revisando la página de GitHub de Hugo encontré una comunidad activa con pipelines sólidos, así que le voy a dar una oportunidad.

Nginx fue una elección difícil para mí, porque siempre he sido un ‘chico de Apache’, pero de nuevo, estoy abierto a aprender. Le pedí a Claude Code que hiciera una investigación en profundidad sobre rendimiento. Suelo sobre-optimizar el rendimiento en mi código cuando los requisitos del proyecto lo permiten, y soy una persona curiosa, así que ¿por qué no revisar datos antes de elegir?

Aquí está el resultado:


Nginx vs Apache — Benchmarks de rendimiento

Uso de RAM

Escenario Nginx Apache (Event MPM)
En reposo ~50–100 MB ~60 MB
100 conexiones concurrentes ~15–20 MB ~40–60 MB
1.000 conexiones concurrentes ~25–35 MB ~150–250 MB
10.000 conexiones concurrentes ~50–100 MB ~2–5 GB

En reposo, ambos servidores son prácticamente equivalentes. La diferencia crece dramáticamente bajo carga: a 10.000 conexiones concurrentes, Nginx usa entre 20 y 100 veces menos RAM que Apache.

Por qué: Nginx almacena ~2–5 KB por conexión (solo un file descriptor y estado mínimo). Apache asigna ~14–20 MB por proceso o hilo.


Uso de CPU

  • Nginx: ~120.000 req/s sirviendo archivos estáticos (servidor x86 moderno)
  • Apache: ~70.000 req/s — 1,7x menos throughput
  • A 512 conexiones concurrentes: Nginx 28.400 req/s vs Apache 15.200 req/s

Por qué: Apache genera miles de context switches (un proceso o hilo por petición). Nginx usa un event loop no bloqueante — un solo worker gestiona más de 10.000 conexiones simultáneas sin overhead de context switch.


Espacio en disco

Nginx Apache
Binario ~1–6 MB (ARM: ~1,3 MB) ~10 MB
Instalación completa ~10–20 MB ~50–100 MB

Apache incluye un directorio de módulos dinámicos (archivos .so separados), múltiples archivos de configuración y soporte de .htaccess por directorio. Nginx es más monolítico — los módulos se compilan dentro del binario, manteniendo el footprint pequeño.


Raspberry Pi (ARM) — Números reales

Benchmark ejecutado directamente en una Raspberry Pi:

  • Nginx: 1.067 req/s
  • Apache: 9 req/s

Cuando Apache se configura con Event MPM y PHP-FPM (sustituyendo mod_php), la diferencia se reduce significativamente (~108–109 req/s cada uno). Sin embargo, Nginx sigue ganando en consumo de recursos.


Conclusión: Para servir contenido estático (sitios generados con Hugo), Nginx es la elección correcta en hardware con recursos limitados como mi Raspberry Pi.

En cuanto al dominio, decidí descartar todos mis dominios y marcas actuales, ya que estaban pensados para otros propósitos.

Este es un blog personal y soy developer. Es hora de comprar jdgomez.dev

Lo compré en Cloudflare porque es barato y puede proporcionarme HTTPS fácilmente, además de tener un tunnel integrado para gestionar mi dirección dinámica. Mi ISP ofrece la opción de IP estática — eso fue lo primero que consideré — pero a ~€144/año no tiene sentido para un blog personal.

Pasos seguidos

Normalmente también publicaré los comandos para conseguir el resultado del que hablo, porque este es un blog sobre procesos (mentales y técnicos), no sobre objetivos.

Releyendo el artículo antes de publicarlo, me di cuenta de que los pasos rompían el ritmo narrativo y no aportan información especialmente útil (son bastante simples), pero al mismo tiempo no quiero eliminarlos. Soy developer, al fin y al cabo.

La solución es ocultarlos. Échales un vistazo si te interesa.


Pasos y comandos
  1. Instalados Hugo y Nginx via apt:
    • Hugo v0.131.0 extended (arm64)
    • Nginx 1.26.3
  2. Creado el sitio Hugo en /home/pi/blog/ con hugo new site blog
  3. Configurado hugo.toml (baseURL, idioma, título)
  4. Creado layout mínimo en layouts/index.html (sin tema externo) con Hello World
  5. Generado el sitio con hugo → output en /home/pi/blog/public/
  6. Configurado Nginx para servir /home/pi/blog/public/ en el puerto 80
  7. Desactivado el sitio por defecto de Nginx
  8. Dados permisos de ejecución en /home/pi para que www-data pueda leer el directorio
  9. Verificado acceso desde la red local → “Hello World”

Estructura de archivos relevante

/home/pi/blog/
├── hugo.toml          ← configuración del sitio
├── layouts/
│   └── index.html     ← layout de la home (sin tema externo)
└── public/            ← output generado por Hugo (lo que sirve Nginx)
    └── index.html

/etc/nginx/sites-available/blog   ← config de Nginx
/etc/nginx/sites-enabled/blog     ← symlink activo

Consideraciones finales

Aunque soy español, el idioma principal del blog debería ser el inglés, “el idioma del developer”, e incluir mi lengua nativa como opción secundaria. Actualmente estoy aprendiendo alemán, pero es demasiado pronto para eso. Quiero añadirlo cuando llegue el momento de ponerlo en práctica, pero no quiero hacer traducciones automáticas. Soy como soy, y eso incluye mi idioma.

Siempre me ha gustado el blog de Uncle Bob, claro y sencillo.

Así que opté por un tema personalizado mínimo, creado desde cero por Claude Code, con instrucciones claras:

“Soy un developer que odia las cookies, mis ojos prefieren los temas oscuros.”

Esta fue su solución:

No podría gustarme más.

El final

Eso es todo. Así empieza todo esto. En el futuro planeo añadir métricas de tiempo más precisas sobre cuánto me cuestan estos pequeños proyectos, incluyendo la redacción del artículo, pero esta vez no lo medí correctamente, así que considerémoslo una mejora para próximas entregas.

Espero que lo hayas disfrutado.

Gracias por leer.