Deconstruyendo esta web

Así está hecha esta web. Funciona sobre Cloudflare, una red de centros de datos repartidos por el mundo, y cada dato enlaza al fichero que lo demuestra.

Cuatro capas, en Cloudflare

capa 1 · Cloudflare

La red

Cómo llega una visita hasta esta web.

Cuando escribes la dirección, responde el DNS de Cloudflare. La zona está firmada con DNSSEC, una firma que permite comprobar que la respuesta no se ha alterado por el camino. La conexión se cifra como mínimo con TLS 1.3 y, en los navegadores que lo admiten, ni siquiera el nombre del sitio viaja en claro. Al otro lado no hay un servidor propio: responde un Worker, un programa que Cloudflare ejecuta en el centro de datos más cercano a quien visita.

visitanteabre una páginaDNSSECzona firmadaTLS 1.3Encrypted Client Hello
Custom Domainscertificado automático
Workersel origen
Panel de Cloudflare: versión mínima de TLS 1.3, TLS 1.3 activado y Encrypted Client Hello activado
El panel de Cloudflare de la zona: TLS 1.3 como mínimo y Encrypted Client Hello activado.
Detalle y pruebas 3 filas
  1. 1.1

    El DNS es autoritativo en Cloudflare y la zona está firmada con DNSSEC.

    sin fichero: se comprueba en la API de la zonaDNS en configuración completa · DNSSEC
  2. 1.2

    TLS 1.3 es la versión mínima que acepta la zona. Encrypted Client Hello está activo. Los clientes que lo admiten reciben además el acuerdo de claves poscuántico que Cloudflare ofrece por defecto.

    sin fichero: se comprueba en la API de la zonaTLS mínimo · Encrypted Client Hello · poscuántico
  3. 1.3

    Always Use HTTPS redirige el HTTP plano en el borde. La aplicación envía HSTS con un año de max-age, includeSubDomains y preload.

capa 2 · Cloudflare

La caché

Qué páginas se guardan ya hechas y cuándo se borran.

Delante del Worker está la caché de Cloudflare, que guarda copias de las páginas en cada centro de datos. Si la página que pides ya está guardada, se entrega sin ejecutar el Worker. Solo se guardan las páginas que lo piden expresamente, y al publicar un cambio desde el gestor de contenidos (el CMS) se borran, por etiqueta, esa página y las que la incluyen en un listado.

Detalle y pruebas 5 filas
  1. 2.1

    Workers Cache está delante del Worker y es escalonada por defecto: un acierto no ejecuta el Worker.

  2. 2.2

    Una página renderizada solo se guarda en el borde si lo pide. Las respuestas que no declaran su propia caché salen con no-store.

  3. 2.3

    Publicar una entrada purga, por etiqueta de caché, sus páginas y las que la listan. Menús y ajustes no se purgan: caducan antes de una hora.

  4. 2.4

    Lo compilado bajo /_astro/ lleva hash de contenido y se sirve con un año de max-age, immutable.

  5. 2.5

    Las imágenes redimensionadas se guardan en la Cache API.

    sin fichero: en la dependencia @astrojs/cloudflareCache API

capa 3 · Cloudflare

Cómputo

Dónde se ejecuta el código que genera cada página.

Toda la web la genera un solo Worker con Astro, un framework que monta cada página en el momento en que se pide. Los ficheros que no cambian, como estilos, scripts e imágenes, se sirven directamente, sin ejecutar código. No hay ningún servidor detrás, y antes de responder el Worker añade siete cabeceras de seguridad a cada página.

Detalle y pruebas 5 filas
  1. 3.1

    Un solo Worker renderiza las páginas bajo demanda con Astro (SSR). Los ficheros compilados se sirven como Workers Static Assets sin ejecutarlo. No hay servidor detrás del Worker.

  2. 3.2

    El equipo que hace Astro trabaja en Cloudflare desde enero de 2026. Astro sigue con licencia MIT y gobierno abierto.

    sin fichero: lo cuenta el anuncioanuncio
  3. 3.3

    Un middleware pone 7 cabeceras de seguridad en cada página que renderiza el Worker. La CSP admite un único script de fuera: el contador de visitas de Cloudflare.

  4. 3.4

    El Worker sabe la ciudad del visitante y qué centro de datos de Cloudflare respondió (request.cf). La apertura de seguridad en el borde los muestra.

  5. 3.5

    Los plugins del CMS pueden ejecutarse en su propio Dynamic Worker, sin red propia y con límites fijos de CPU, subpeticiones y tiempo. Todo lo que hacen pasa por un puente que comprueba las capacidades que declara cada uno.

capa 4 · Cloudflare

Datos

Dónde se guarda cada cosa.

Los textos y su historial viven en D1, la base de datos SQLite de Cloudflare. Las sesiones de quien edita se guardan en Workers KV, un almacén de pares clave y valor; Images ajusta a su hueco las fotografías que se redimensionan y las convierte a WebP, y R2, el almacenamiento de ficheros, queda listo para lo que se suba desde el CMS. La versión de pruebas y la de producción no comparten ninguno de los cuatro.

Panel de Cloudflare: los bindings del Worker de producción, D1, Images, Dynamic Workers, R2 y KV
Los bindings del Worker en el panel de Cloudflare. El sexto, ASSETS, lo añade el adaptador de Astro al compilar.
Detalle y pruebas 5 filas
  1. 4.1

    D1 (SQLite) guarda el contenido, sus revisiones y los ajustes. Cada petición abre una sesión de D1.

  2. 4.2

    Workers KV guarda las sesiones de los editores.

  3. 4.3

    Las fotografías que la página redimensiona pasan por el binding de Images, que las ajusta a su hueco y las convierte a WebP. El resto se sirve tal como está en el repositorio.

  4. 4.4

    R2 está conectado como almacén de medios del CMS. Hoy cada imagen del sitio viaja con el código.

  5. 4.5

    Preview y producción tienen cada una su D1, su Workers KV y su R2.

Dentro del Worker

dentro del Worker

Presentación

Cómo se dibuja lo que ves.

La interfaz está hecha con Astro y una sola hoja de estilos. Fuentes, scripts e imágenes salen del propio sitio; lo único que se pide fuera es el contador de visitas de Cloudflare. Las aperturas de cada sección combinan fotografías restauradas con un dibujo que se anima en el navegador.

La apertura de seguridad en el borde en reposo: el faro de Cabo Peñas con su perfil en naranja y el barrido del radar
Cabo Peñas · Einaz80 · CC BY-SA 4.0
La apertura de desarrollo greenfield en reposo: el museo Guggenheim de Bilbao desde la ría
Guggenheim · Sergio S.C · CC BY-SA 2.0
1proveedor de fuera al que llama el navegador: Cloudflare
una hoja de estilos para todo
Detalle y pruebas 7 filas
  1. 5.1

    Una hoja de estilos declara cada color, radio y sombra, el ancho de columna y la escala de espaciado. CI rechaza esos valores escritos en otro sitio, salvo en bloques marcados que imitan la interfaz de otro producto.

  2. 5.2

    Fuera del sitio, el navegador solo llama a Cloudflare: descarga el script de Web Analytics y le envía sus mediciones, sin cookies y sin identificar a nadie. Fuentes, imágenes y el resto de scripts son del propio sitio. Zaraz, el gestor de etiquetas de Cloudflare, se carga en cada página desde este mismo dominio y recibe la respuesta que das en el aviso de cookies. Si aceptas la analítica, envía la visita a Google Analytics 4 desde los servidores de Cloudflare: ni siquiera entonces llama el navegador a Google. Si la rechazas, Google Analytics 4 no llega a ejecutarse.

  3. 5.3

    Las fuentes están en el repositorio, así que construir la web no depende de Google Fonts. Cloudflare Fonts no aplica: solo reescribe los enlaces a Google Fonts, y aquí no hay ninguno.

  4. 5.4

    Cada vertical abre con una fotografía de Wikimedia Commons, restaurada y redibujada en parte, y una capa dibujada en vivo en el navegador. La capa se coloca según el texto medido, y su reloj se para a los ocho segundos: nada se repite.

  5. 5.5

    Las fotografías se restauraron en local con SeedVR2. FLUX.2 [dev] (Black Forest Labs) en Workers AI retiró objetos, amplió encuadres y redibujó a partir de las fotografías. Cada prompt está en el repositorio.

    docs/design/hero-rotativo/photo_restore.py[FLUX.2 [dev]](https://developers.cloudflare.com/workers-ai/models/flux-2-dev/)
  6. 5.6

    Las fotografías son CC BY-SA y el sitio las acredita con los cambios indicados.

  7. 5.7

    El aviso de cookies lo dibuja el propio sitio. Es una tarjeta en la esquina inferior izquierda, y la página sigue funcionando detrás mientras decides. Aceptar y Rechazar son dos botones iguales, uno al lado del otro. El aviso no tiene cierre y espera a tu respuesta; «Preferencias de cookies», en el pie, lo vuelve a abrir. La ventana propia de Zaraz está apagada porque bloquea la página entera, y la guía de la AEPD no pide tanto. Pide rechazar al mismo nivel que aceptar, un aviso que se mantenga hasta que respondas y retirar el consentimiento con la misma facilidad. Solo tu clic pasa la respuesta a Zaraz, a través de su API de consentimiento. Google Analytics 4 sobra para contar visitas, porque ya lo hace Web Analytics. Está porque esta web también es un laboratorio.

dentro del Worker

El CMS: EmDash

Dónde se edita el contenido.

El CMS de esta web es EmDash, el gestor de contenidos de código abierto de Cloudflare, y corre dentro del mismo Worker que sirve las páginas. Desde su panel se editan páginas, servicios, menús y cada etiqueta de la interfaz, en español y en inglés. Al publicar, un plugin guardado en el repositorio borra de la caché lo que ha cambiado.

El editor de EmDash con la página Deconstruyendo esta web abierta
El editor de EmDash, en el admin del sitio.
Detalle y pruebas 10 filas
  1. 6.1

    EmDash, el CMS de código abierto (MIT) que Cloudflare anunció en abril de 2026, corre dentro del mismo Worker.

  2. 6.2

    Cloudflare publica su propio blog con EmDash.

    sin fichero: lo cuenta su blogel blog de Cloudflare
  3. 6.3

    Cinco tipos de contenido: páginas, servicios, miembros, referencias y partners, con entradas de blog preparadas y vacías. Páginas y servicios tienen borradores; esos dos y miembros guardan revisiones. Los cuerpos son Portable Text.

  4. 6.4

    Dos idiomas: páginas, servicios y miembros se publican en pares enlazados por translationOf.

  5. 6.5

    Menús, áreas de widgets, ajustes del sitio y taxonomías vienen del CMS. Cada etiqueta de la interfaz vive en un widget, no en una plantilla.

  6. 6.6

    La búsqueda es la de EmDash, sobre SQLite FTS5 con ranking bm25.

    sin fichero: en EmDash, migración 064
  7. 6.7

    El admin admite editores solo con passkey (WebAuthn): no hay contraseña que guardar ni que filtrar.

    sin fichero: lo responde /_emdash/api/auth/modeautenticación
  8. 6.8

    EmDash es también un servidor de autorización OAuth (perfil OAuth 2.1: código + PKCE, registro dinámico de clientes). Por eso un agente de IA puede trabajar en el contenido a través de su servidor MCP, con un token que concede un editor.

    sin fichero: lo responden los endpoints del adminservidor MCP · herramientas de IA
  9. 6.9

    La línea de comandos emdash inicia sesión con el flujo de dispositivo de OAuth (RFC 8628).

    sin fichero: lo responde /_emdash/.well-known/authservidor MCP
  10. 6.10

    Un plugin guardado en el repositorio purga la caché al publicar. Declara content:read, porque sin él EmDash se salta sus hooks.

Transversal, desde el taller

transversal · desde el taller

Entrega

Cómo llega un cambio a producción.

El código vive en un repositorio de GitHub. Cada cambio entra como una propuesta revisable, un pull request, y pasa 27 pasos de comprobación automáticos (la integración continua, o CI) sobre una copia local del sitio. Si todos pasan, la versión de pruebas se despliega sola con wrangler, la herramienta de despliegue de Cloudflare. Producción se despliega a mano, y una guarda impide sobrescribir una base de datos que ya tiene contenido.

Una ejecución de deploy-preview en GitHub Actions: deploy y verify en verde
La preview se despliega sola después de que pasen las puertas, en GitHub Actions.
Detalle y pruebas 5 filas
  1. 7.1

    El repositorio de trabajo es público, con todos sus commits.

  2. 7.2

    Cada cambio que puede llegar a una página pasa 27 pasos que pueden fallar. Un test deriva ese número del workflow.

  3. 7.3

    Las puertas ejecutan el sitio en local sobre workerd, el runtime de código abierto de Workers, con wrangler dev. Si wrangler se cae por un fallo suyo, la pila se reinicia una vez y el resumen lo dice.

  4. 7.4

    Cuando las puertas pasan en main, la preview se despliega sola con wrangler-action. Espera a las migraciones de D1, vuelve a sembrar tras ensayar el SQL en una base desechable y lanza una batería de humo.

  5. 7.5

    Producción solo se despliega cuando el fundador lo arranca a mano, y una guarda se niega a sobrescribir una base de datos que tiene contenido.

transversal · desde el taller

Contenido

Dónde está escrito cada texto.

Todo el texto de la web está en un fichero del repositorio, seed/seed.json, en español y en inglés. En cada cambio, la integración continua construye el sitio y llena con ese fichero una base de datos vacía, así que la web entera se puede rehacer desde cero en cualquier momento.

La carpeta seed del repositorio en GitHub, con seed.json y la carpeta content
La carpeta seed/ del repositorio público.
Detalle y pruebas 4 filas
  1. 8.1

    Cada frase que renderiza el sitio vive en un fichero versionado, seed/seed.json. Las páginas de servicio se escriben en Markdown y el CMS las convierte a ese fichero. Un test mantiene los dos palabra por palabra, y una puerta de CI rechaza el texto escrito en una plantilla.

  2. 8.2

    En cada cambio que puede llegar a una página, CI compila el sitio y llena una base de datos vacía desde ese fichero, doce veces en paralelo.

  3. 8.3

    Los slugs de servicio están traducidos, así que la URL del otro idioma nunca se adivina. hreflang y el selector de idioma leen el mismo valor resuelto.

  4. 8.4

    El sitemap se genera desde las colecciones del CMS.

transversal · en cada cambio

Calidad

Qué se comprueba antes de publicar nada.

Las comprobaciones de accesibilidad, diseño, textos e idiomas plantan primero el defecto que buscan y solo dan verde si lo encuentran. Lighthouse, la herramienta de Google que puntúa rendimiento y accesibilidad, mide nueve páginas; el texto de 30 rutas está congelado, y cada apertura se prueba con los motores de Safari y de Chrome. Agentes de IA escriben la mayor parte del código, y el fundador fusiona cada cambio.

27pasos que pueden fallar
30rutas con el texto congelado
≥95rendimiento
100accesibilidad
100buenas prácticas
100SEO
Lighthouse en 9 páginas, en CI contra una copia local, el 2026-10-16
Una ejecución de quality-gates en GitHub Actions con todos los trabajos en verde
Las puertas de un cambio en main, todas en verde, el 2026-10-16.
Detalle y pruebas 7 filas
  1. 9.1

    Las comprobaciones de accesibilidad, motores, diseño, maquetación, textos, idiomas y nombres plantan el defecto que buscan, y tienen que cazarlo antes de dar verde.

  2. 9.2

    Lighthouse en CI, contra una copia local, con la mediana de 3 pasadas en 9 páginas: rendimiento ≥95; accesibilidad, buenas prácticas y SEO, 100. Las nueve lo cumplieron el 2026-10-16.

  3. 9.3

    Accesibilidad: axe (WCAG 2.2 A+AA) y un recorrido con teclado en todas las rutas del sitio, más reflujo a 320 px. Donde hay texto sobre una fotografía, el contraste se mide en los píxeles renderizados.

  4. 9.4

    Cada apertura se comprueba a mitad de animación y en reposo, con el motor de Safari (perfiles de iPhone y de escritorio) y el de Chrome (Pixel 7), también con movimiento reducido.

  5. 9.5

    El texto renderizado de 30 rutas está congelado. Cambiar una palabra falla hasta que el texto nuevo se captura a propósito, así que el cambio se ve en el diff del pull request.

  6. 9.6

    Agentes de IA escriben la mayor parte del código bajo reglas escritas, y el fundador fusiona cada pull request.

    sin fichero: lo muestra el historial de fusionesel repositorio
  7. 9.7

    Cada push se analiza en busca de secretos, y una guarda rechaza cualquier nombre de cliente que no esté publicado en Referencias.

El taller, abierto

Si te cuentan cómo trabajan y no pueden enseñarte el taller, desconfía. Este es el nuestro: código, contenido, comprobaciones y despliegues.

Ver el repositorio

Hablemos de ingeniero a ingeniero.

Trae el problema como esté. Te responde quien va a escribir el código.

Cuéntanos tu proyecto