Cómo preparamos un sitio de hosting compartido para el mantenimiento con Cloudflare Workers
Respuesta rápida
Un sitio PHP principalmente estático puede seguir siendo útil durante una caída planificada sin trasladar la cuenta activa. El Worker delante de KeyboardTester.click deja pasar intacta cada respuesta sana y, ante fallos de red o errores de servidor seleccionados, sirve una instantánea estática. En cuanto el origen vuelve, la siguiente respuesta sana recupera el servicio automáticamente. Es continuidad práctica, no cero interrupciones universal: formularios, correo, IA del servidor y acciones guardadas siguen dependiendo del hosting.
El aviso indicaba una ventana de mantenimiento de seis horas, pero no la duración exacta de la caída. Esperar un correo dejaba un hueco manual; cambiar DNS hacia una sola página mantenía el aviso, no el contenido ni las herramientas que el visitante buscaba.
Este es el diseño que desplegamos de verdad: conversación con HostArmada, lógica del Worker, captura, trampa de recursión, protecciones del plan gratuito, SEO, anuncios, analítica y límites.
Nota temporal: a 18 de julio de 2026, el mantenimiento aún no ha ocurrido. Los resultados proceden de fallos forzados del origen, staging privado, auditoría del snapshot y paso saludable en producción, no de la ventana real.
Lo que aclaró el ticket de HostArmada
La ventana era el 22 de julio de 2026, de 10:00 a 16:00 CDT. Preguntamos si serían seis horas continuas, si podían migrar temporalmente la cuenta, qué servicios caerían, si habría un endpoint externo 503 para todas las URL, qué rollback existía y cómo se evaluaría un crédito.
Tras escalarlo, administración explicó que las seis horas eran una reserva, no seis horas confirmadas de caída. Esperaban menos tiempo, pero sin cifra exacta por los cambios físicos, actualizaciones y verificación. Mover y devolver la cuenta podía sumar riesgos de DNS, sincronización, correo y base de datos.
HostArmada ofreció razonablemente un vhost en otro servidor con una página de mantenimiento. Nosotros cambiaríamos el registro A al empezar y lo restauraríamos al finalizar. El DNS externo seguiría resolviendo, pero web, base de datos, correo y panel del servidor afectado no responderían. Había copias y recuperación; cualquier crédito se revisaría según el impacto real. Era una solución justa para informar, pero manual y sin continuidad funcional.
That offer was fair for a maintenance notice. It was still manual and did not provide functional-site continuity, so we used it as the baseline to improve rather than portraying it as a provider failure.
Cronología verificable: del correo de mantenimiento a la continuidad probada
La secuencia separa el anuncio, nuestras preguntas, lo construido y probado, y el evento real que todavía no ha ocurrido.
- Julio de 2026 — correo recibido
El aviso de Start Dock reservó el 22 de julio, 10:00–16:00 CDT: actualización de CPU, RAM y SSD; seguridad/software web; kernel; limpieza de tmp, caché y logs; optimización general. Indicó que el procedimiento no sería reversible una vez iniciado.
- Servidor compartido Start Dock
- 22 de julio de 2026, 10:00–16:00 CDT
- Actualización de CPU, RAM y SSD
- Seguridad/software del servidor web
- Actualización del kernel
- Limpieza de tmp, caché y logs
- Optimización general
- Procedimiento no reversible tras comenzar
- 16 de julio — preguntas escaladas
Pedimos duración real, migración, endpoint 503 externo, impacto en web/DB/correo, backup, rollback y crédito.
- 17 de julio — respuesta de HostArmada
Seis horas eran la ventana, la caída sería probablemente menor; descartaron mover la cuenta por sincronización y ofrecieron vhost más A record manual.
- Diseño elegido el 17 de julio; seguimiento enviado el 18
Worker permanente origin-first, snapshot, staging privado, control de colisiones, 503 y rollback definidos.
- 17–18 de julio — implementación controlada
1.514 páginas y 1.234 assets capturados, 2.748 rutas auditadas, fallo/paso probados, recursión resuelta y apex/www fail-open activos.
- 18 de julio — preparado, evento pendiente
La capa está activa y probada; el mantenimiento del día 22 aún no ha ocurrido. Duración, tráfico e ingresos reales esperan evidencia posterior.


Arquitectura: primero el origen, copia solo al fallar
El Worker permanece en las rutas del dominio raíz y www. Consulta el origen con un tiempo límite. Si responde bien, lo entrega sin tocar: PHP, sesiones, cabeceras, anuncios y analítica se comportan con normalidad.
Si hay error de red, timeout, 500, 502, 503, 504 o 520–527, busca la misma ruta en los activos estáticos. GET y HEAD siguen funcionando. Cada petición posterior vuelve a probar el origen y la recuperación es automática.
La copia no es un segundo entorno PHP. Así evitamos dos bases escribibles, conflictos de sesión, correo duplicado y reconciliación de datos.
Flujo de una petición

Página temporal del proveedor frente a continuidad con Worker
Ambas sirven: la página de mantenimiento conserva semántica correcta con poco montaje; el snapshot mantiene navegables la mayoría de contenidos y herramientas del navegador.
| Pregunta | Vhost temporal del proveedor | Worker permanente |
|---|---|---|
| Cambio | DNS manual al inicio y final | Automático por petición |
| Qué ve el visitante | Una página de mantenimiento | Página, herramienta o activo correspondiente |
| Escrituras | No disponibles | No disponibles; 503 explícito |
| Recuperación | Restaurar DNS manualmente | Automática al sanar el origen |
| Consistencia | Riesgo bajo sin segunda base | Riesgo bajo sin segunda base |
| Operación | Simple, pero exige acción puntual | Más preparación, poca acción durante el evento |
Qué reciben usuarios y rastreadores durante el fallo
Páginas, herramientas del cliente, CSS, scripts, imágenes y fuentes se sirven desde la copia con un aviso discreto. Canonical y datos estructurados continúan en las URL originales.
Las acciones de escritura no fingen éxito. POST y acciones desconocidas devuelven 503 Service Unavailable, Retry-After: 300 y Cache-Control: no-store. RFC 9110 define 503 para mantenimiento temporal y permite indicar cuándo reintentar.
This distinction matters: returning a pretty 200 OK “maintenance” page for a failed form can mislead users and crawlers. Returning a controlled 503 for the unavailable action is both more honest and easier for clients to retry.
Matriz real de fallback
| Resultado del origen | GET / HEAD | POST o escritura |
|---|---|---|
| Sano, redirect, 4xx o fuera del conjunto | Pasar origen intacto | Pasar origen intacto |
| Fallo de red o timeout de 4,5 s | Snapshot correspondiente; 503 si falta | 503 + Retry-After: 300 + no-store |
| 500/502/503/504 o 520–527 | Snapshot correspondiente y header diagnóstico | 503 + Retry-After: 300 + no-store |
| Ruta segura desconocida sin origen | 503 controlado; nunca inventar página | No aplica |
Cómo construimos y verificamos la copia
Rastreamos producción renderizada, no el árbol PHP local con cambios sin publicar. Capturamos 1.514 páginas y 1.234 activos propios. El despliegue sumó 2.749 archivos y unos 547,6 MB, todos bajo el límite individual.
Conservamos canonical y schema, corregimos referencias relativas antiguas solo en la copia y quitamos rastreadores durante la captura. El Worker de producción añade GA4, AdSense y Clarity solo en portada; staging es privado, sin tracking y noindex.
Las pruebas incluyeron TypeScript, unidades, caída local forzada, staging autenticado, navegador, vista del origen y auditoría remota completa: funcionaron las 2.748 rutas públicas de página y activo.
- Separar ventana de mantenimiento y caída esperada.
- Construir desde producción renderizada si local no coincide.
- Inventariar páginas y activos; validar número y tamaño.
- Mantener staging privado/noindex y probar fallo y paso sano.
- Definir métodos, estados, timeout, 503 y rollback.
- Evitar recursión de zona y conservar el Host canónico.
- Elegir fail-open solo si saltar el Worker es más seguro.
- Documentar funciones sin soporte y actualizar la copia.

Cómo reproducirlo con seguridad: pasos y código saneado
1. Define el contrato. Hosts, métodos seguros, estados de fallo, timeout, rutas desconocidas y retirada de rutas. No todo lo que no sea 200 es caída.
2. Rastrea producción renderizada. Parte del sitemap canónico, descubre recursos same-origin de HTML/CSS, normaliza URL, bloquea traversal y detén el build si se superan límites.
3. Conserva significado. Mantén canonical, hreflang, schema, enlaces y assets de herramientas; retira service worker y tracking. Inyecta anuncios/analítica solo en producción.
4. Vincula ASSETS. Usa run_worker_first para probar el origen antes de la copia. Los ejemplos solo contienen placeholders.
5. Evita recursión. Usa un hostname DNS-only controlado de la misma zona para resolveOverride, conservando URL y Host canónicos; verifica TLS y virtual host.
6. Staging privado. Secreto, noindex, robots bloqueado, sin anuncios ni analítica y vista explícita del origen.
7. Añade rutas una a una. Rechaza colisiones, prueba apex y después www/redirect; fail-open solo si el Worker no aplica seguridad.
8. Separa el rollback. Quita únicamente rutas propias, conserva Worker/snapshot y revoca permisos temporales.
Configuración saneada de Worker y assets
{
"name": "example-host-outage-fallback",
"main": "src/index.ts",
"compatibility_date": "2026-07-17",
"assets": {
"directory": "./snapshot/dist",
"binding": "ASSETS",
"run_worker_first": true,
"html_handling": "none",
"not_found_handling": "none"
},
"vars": {
"MODE": "production",
"ORIGIN_BASE": "https://example.com",
"ORIGIN_RESOLVE_OVERRIDE": "origin-bypass.example.com",
"ORIGIN_TIMEOUT_MS": "4500"
}
}Decisión origin-first y matriz de estados
const FALLBACK_STATUSES = new Set([
500, 502, 503, 504, 520, 521, 522, 523, 524, 525, 526, 527
]);
try {
const origin = await fetch(originRequest, {
signal: AbortSignal.timeout(4500),
redirect: "manual",
cf: { resolveOverride: "origin-bypass.example.com" }
});
if (!FALLBACK_STATUSES.has(origin.status)) return origin;
return serveSnapshot(request, origin.status);
} catch {
return serveSnapshot(request);
}503 honesto para escrituras
if (!new Set(["GET", "HEAD"]).has(request.method)) {
return new Response("Temporarily unavailable", {
status: 503,
headers: {
"Retry-After": "300",
"Cache-Control": "no-store",
"Content-Type": "text/plain; charset=utf-8"
}
});
}Construir, probar, activar y revertir
# Build from rendered production and validate the package
python scripts/build_snapshot.py
npm run types
npm run check
npx wrangler deploy --env staging --dry-run
# Deploy and test the private preview (use your own secret securely)
npx wrangler deploy --env staging
python scripts/smoke_staging.py --base "https://<private-preview>" --password "<secret>"
# Inspect, activate, or remove only the owned routes
python scripts/manage_routes.py status
python scripts/manage_routes.py activate --confirm ACTIVATE-KBT-FALLBACK
python scripts/manage_routes.py deactivate --confirm REMOVE-KBT-FALLBACKPlan de pruebas: demostrar fallo, paso y recuperación
Prueba portada, herramienta principal, CSS/JS, artículo, árabe RTL, localización larga, robots, ruta ausente, HEAD, POST, redirect www y temas claro/oscuro móvil.
En snapshot revisa header, canonical, H1, JSON-LD, assets y aviso; en origin preview acceso directo sin bucle; en producción sana, ausencia del header y respuesta/redirect/tracking intactos.
Nunca rompas el origen público. Usa preview privado u origen de fallo separado y registra fecha del snapshot y hash del manifiesto.
Rollback, vigilancia y recuperación
La reversión inmediata es retirar solo las rutas propias, no cambiar DNS ni borrar el Worker. Comprueba apex/www y purga solo si queda HTML antiguo.
Durante el evento vigila headers, estado del origen, logs, páginas clave y 503. La primera respuesta sana retoma automáticamente. Después confirma estabilidad, revoca permisos, archiva métricas y renueva la copia.
Dos trampas: recursión en la misma zona y cuota gratuita
Un Worker sobre keyboardtester.click/* no debe volver a pedir ingenuamente ese host público. Usamos resolveOverride con un hostname DNS-only existente en la misma zona: resuelve al origen, pero conserva la URL y Host canónicos. La dirección del origen y la infraestructura de bypass no deben publicarse.
El plan Free permite hoy 100.000 peticiones Worker diarias, 20.000 activos por versión y 25 MiB por archivo. Nuestros 2.749 archivos caben. Las rutas están fail-open: agotada la cuota, Cloudflare omite el Worker y va a HostArmada en vez de mostrar Error 1027. Es adecuado para disponibilidad, no para controles de seguridad.
SEO, anuncios y analítica en el fallback
Las páginas existentes se sirven con 200, canonical, schema y enlaces internos en sus URL originales; las escrituras no disponibles reciben 503. No hay dominio de copia público ni URLs nuevas que enviar.
Staging tiene contraseña, robots bloqueado, noindex y sin medición. Solo el HTML de producción recibe GA4 y AdSense diferidos; Clarity se limita a la portada. Las respuestas sanas del origen no cambian. Esto conserva medición y posible entrega publicitaria, nunca garantiza llenado ni ingresos.
We did not submit fallback URLs to search engines because there are no new public URLs. The continuity layer sits behind the same addresses Google already knows.
La inyección de producción replica el rendimiento live: GA4 tras interacción o 2 segundos desde load, AdSense tras interacción o 15 segundos y Clarity solo en portada tras interacción o 12 segundos. HTMLRewriter en streaming modifica únicamente HTML GET de fallback, nunca HEAD, CSS, JS ni imágenes.
Límites y cuándo elegir otra arquitectura
Formularios, IA del servidor, correo, escrituras, sesiones y envíos guardados no funcionan sin el origen. Una herramienta puramente local funciona solo si todos sus archivos están en la copia.
La instantánea envejece: hay que renovarla tras cambios importantes y probar también la recuperación. Un producto transaccional o de escritura intensiva necesita aplicación y base de datos replicadas.
Para un sitio de contenido con hosting compartido y herramientas del navegador fue un buen ajuste: sin división de datos, sin corte manual, sin dominio duplicado y con degradación clara. Reduce la ventana visible; no elimina cada dependencia.
Fuentes primarias y evidencia propia
Las cifras proceden de manifiestos y verificaciones de despliegue y rutas del 17–18 de julio de 2026. El comportamiento y los límites están respaldados por documentación primaria.
- Cloudflare Workers: Static Assets
- Cloudflare Workers: Platform Limits
- Cloudflare Workers Request API
- Cloudflare Workers Routes API
- RFC 9110: HTTP Semantics
- HostArmada support correspondence, July 16–17, 2026
Preguntas frecuentes
- ¿Esto vuelve realmente cero-downtime al hosting compartido?
No. Mantiene una copia de lectura; formularios, escrituras, correo, IA y sesiones siguen necesitando el origen.
- ¿Tengo que cambiar DNS cuando cae el host?
No con este patrón permanente. El Worker prueba el origen en cada petición y vuelve automáticamente.
- ¿Google ve una página de mantenimiento en cada URL?
No. Las páginas presentes conservan 200, canonical y schema; las acciones no disponibles reciben 503 temporal.
- ¿Por qué no migrar toda la cuenta temporalmente?
Mover y devolver puede crear riesgos de DNS, archivos, correo y base de datos. Evitamos un segundo stack escribible.
- ¿Por qué usar resolveOverride?
Evita que el Worker pida su propia ruta pública. Resuelve mediante otro host de la misma zona y conserva URL y Host canónicos.
- ¿Qué ocurre al agotar el límite gratuito?
Las rutas son fail-open: Cloudflare salta el Worker y va al origen. Se pierde el fallback si el origen cae, pero no aparece un error de cuota adicional.
- ¿Cuándo hay que actualizar el snapshot?
Tras cambios importantes de contenido, plantilla, scripts o activos y antes de un mantenimiento, probando fallo y recuperación.
La lección no es ponerlo todo detrás de un Worker, sino elegir la capa mínima adecuada, probarla en privado, reconocer sus límites y automatizar la recuperación.