Este sitio

Astro, compilado a archivos estáticos. Sin runtime, sin base de datos detrás, sin framework enviado al navegador, sin rastreo ni analítica. Cada color, tamaño y duración sale de un solo archivo de tokens, y diecisiete verificaciones de render — contraste, operación por teclado, tamaño de los objetivos, movimiento reducido, espejado RTL, desbordamiento silencioso — corren sobre cada página en ambos temas antes de publicar nada.

El borde

Caddy termina el TLS con certificados que obtiene y renueva solo, sirve sobre HTTP/2, redirige www al dominio raíz y quita las barras finales para que cada página tenga una sola URL, y devuelve el 404 en español a las rutas en español. El contenido se lee del disco en cada petición, así que publicar no reinicia nada.

Cada respuesta lleva

Strict-Transport-Security
max-age=31536000; includeSubDomains
X-Content-Type-Options
nosniff
Referrer-Policy
strict-origin-when-cross-origin
Permissions-Policy
geolocation=(), camera=(), microphone=(), payment=(), usb=()
Content-Security-Policy
default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; font-src 'self'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'

No se permite ningún origen externo. Las fuentes, los estilos y los scripts se sirven desde este mismo servidor, así que nada en la página puede llamar a otro lado.

Escáneres independientes, para que esto se pueda comprobar en vez de solo afirmarlo:

Sacar un cambio a producción

  1. Verificar y hacer pushdiecisiete verificaciones, luego origin
  2. Pullen el servidor, con llave de despliegue
  3. Construir al ladoen un directorio que nadie está sirviendo
  4. Intercambiardos renombrados
Las verificaciones corren antes del push, en mi propia máquina. Llaman scripts que no son parte del repositorio desplegado, así que el servidor no podría correrlas aunque lo intentara.

El intercambio es lo que importa. Astro borra su directorio de salida al empezar un build, así que construir directamente en el directorio que sirve Caddy dejaría el sitio vacío durante todo el build, y vacío del todo si ese build falla. Construir al lado y renombrar hace que el cambio sea prácticamente instantáneo y deja el build anterior en su sitio, así que revertir son los mismos dos renombrados al revés: sin recargar nada y sin reconfigurar nada.

El servidor

Una sola máquina física con Debian que yo instalo, actualizo y de la que respondo. Corre este sitio junto con varios servicios más, descritos aquí por lo que hacen y no por dónde están.

Proxy inverso y TLS
Caddy, delante de cada sitio y servicio de la máquina.
Base de datos relacional
PostgreSQL, en el disco más rápido y deliberadamente fuera de los discos de medios.
Almacenamiento de objetos
Un almacén compatible con S3 para los medios de las aplicaciones.
Contenedores
Docker, con los volúmenes persistentes fijados a un disco aparte para que una partición raíz llena no se lleve el daemon por delante.
Control de versiones y despliegue
Un servidor Git propio con pipelines de push-to-deploy. Cada repositorio tiene su propia llave, así que un pipeline comprometido llega a un proyecto y no al servidor entero.
Inferencia local de modelos
Para trabajo donde los datos no pueden salir de la máquina en la que ya están.
Monitoreo y endurecimiento
Métricas por host con reglas de alerta, monitoreo SMART de discos y fail2ban sobre la superficie expuesta.

Cómo falla

Es una sola máquina en una conexión residencial con dirección dinámica, y vale la pena decirlo sin rodeos en una página sobre confiabilidad. Un actualizador de DNS dinámico vigila esa dirección y la republica cuando cambia, así que un cambio de dirección cuesta el intervalo de consulta más el TTL del registro. No hay una segunda máquina, así que una actualización de kernel tumba todo junto, a propósito y a la hora que yo elija. Ese es el intercambio correcto para un servidor personal y el incorrecto para una empresa, y por eso los sistemas en producción de los casos están construidos de otra manera.