5 playbooks nuevos en docs/playbooks/ del portal: - SQLite en modo DELETE causando SQLITE_BUSY, por que WAL lo resuelve. - Anchors YAML no soportados por el parser de Gitea Actions, incluido el diagnostico equivocado inicial (indentacion) que se corrigio despues -- documentado con honestidad como leccion de proceso. - Docker-in-Docker vs sibling containers, y por que Semgrep corre nativo en un venv en vez de como container aparte. - El SNI/realm HTTP del tunel rompiendo especificamente a Cosign (docker push funcionaba, cosign sign no), conectado con el incidente ya documentado del 504 -- misma capa de ingress, dos fallas distintas. - Contencion de recursos entre Gitea y su runner: causa raiz real confirmada en vivo durante esta misma sesion (ambos contenedores reiniciados a mitad de un build, sin limites de CPU/memoria reales), con fix propuesto (ver rama fix/gitea-runner-resource-limits en scripts/) pendiente de aplicacion manual. Se actualiza el playbook del 504 para linkear hacia el nuevo hallazgo de contencion, cerrando el loop que habia quedado abierto ahi. cosign.md: nueva seccion "Limitaciones conocidas y mejoras futuras" con los dos TODO reales -- firma por tag en vez de digest (con el warning real de Cosign visto en los logs) y transparency log de Rekor deshabilitado, explicado en simple. index.md: tabla resumen de los 3 pipelines (imagen + adaptacion de Semgrep por stack), diagrama generalizado para reflejar que es el mismo patron en los 3 workflows, y "que falta" actualizado. Validado con mkdocs build --strict (0 errores, 0 warnings) antes de commitear.
88 lines
3.8 KiB
Markdown
88 lines
3.8 KiB
Markdown
# Incidente: 504 Gateway Timeout intermitente (túnel QUIC inestable) (2026-08)
|
||
|
||
!!! info "Origen"
|
||
Migrado desde `apps-registry/docs/playbooks/incidente-cloudflared-504-quic-2026-08.md`.
|
||
Contenido técnico preservado sin cambios de fondo — solo formato adaptado a MkDocs Material.
|
||
|
||
| | |
|
||
|---|---|
|
||
| **Ventana del incidente** | Intermitente durante varias horas, 2026-08 |
|
||
| **Servicio afectado** | `cloudflared` (túnel de Cloudflare, app nativa de ZimaOS, red Host) — afecta a **todos** los subdominios detrás del mismo túnel (`gitea.cruzcloud.net`, `commerce.cruzcloud.net`, `shop.cruzcloud.net`, `media.cruzcloud.net`, Immich, Argo CD, Memos, etc.) |
|
||
| **Impacto** | `504 Gateway Timeout` intermitente en peticiones HTTP a cualquier host detrás del túnel, sin patrón evidente de horario ni de carga |
|
||
|
||
## Síntoma
|
||
|
||
`gitea.cruzcloud.net` devolvía `504 Gateway Timeout` de forma
|
||
intermitente. El mismo síntoma se observaba en otros hosts servidos por
|
||
el mismo túnel, lo que apuntaba a una causa **compartida a nivel de
|
||
túnel**, no de una app individual.
|
||
|
||
## Diagnóstico
|
||
|
||
```bash
|
||
docker logs -f cloudflared 2>&1 | grep -i -E "connIndex|protocol|retry"
|
||
```
|
||
|
||
Reveló un patrón sostenido durante horas: la conexión `connIndex=2`
|
||
(de las 4 conexiones que `cloudflared` mantiene hacia el edge de
|
||
Cloudflare) sufría fallos recurrentes de "control stream" cada 2-6
|
||
minutos, reconectándose en loop:
|
||
|
||
```text
|
||
control stream encountered a failure while serving
|
||
Retrying connection in up to 1m4s
|
||
```
|
||
|
||
Cuando una petición HTTP coincidía con el instante exacto de una de
|
||
esas caídas de `connIndex=2`, el cliente recibía el 504.
|
||
|
||
## Causa raíz
|
||
|
||
El contenedor `cloudflared` (imagen oficial `cloudflare/cloudflared:latest`)
|
||
usaba **QUIC (UDP)** como protocolo de transporte por defecto para sus
|
||
4 conexiones hacia el edge de Cloudflare. Una de esas conexiones
|
||
presentaba fallos de control stream recurrentes durante horas.
|
||
|
||
!!! warning "Causa de fondo probable"
|
||
Inestabilidad de UDP/QUIC en la red local (NAT/firewall doméstico).
|
||
QUIC es más sensible que TCP/HTTP2 a NATs agresivos o middleboxes
|
||
que no manejan bien tráfico UDP de larga vida — un patrón común en
|
||
redes domésticas, a diferencia de datacenters con NAT dedicado para
|
||
este tipo de tráfico.
|
||
|
||
## Fix aplicado
|
||
|
||
Se agregó la variable de entorno `TUNNEL_TRANSPORT_PROTOCOL=http2` en
|
||
la configuración del contenedor `cloudflared` (app ZimaOS → Ambiente →
|
||
variables), forzando HTTP/2 sobre TCP en vez de QUIC/UDP.
|
||
|
||
Tras reiniciar el contenedor, el precheck de `cloudflared` confirmó:
|
||
|
||
```text
|
||
Environment is healthy. cloudflared will use 'http2' as primary protocol.
|
||
```
|
||
|
||
y las 4 conexiones pasaron a `protocol=http2`.
|
||
|
||
Ver también el ADR correspondiente:
|
||
[0003 — Por qué HTTP/2 sobre QUIC](../decisiones/0003-por-que-http2-sobre-quic-tunnel.md).
|
||
|
||
## Validación
|
||
|
||
Curl en loop contra `gitea.cruzcloud.net` tras el cambio: latencia
|
||
estable ~0.37–0.4s sostenida por 24+ minutos sin un solo 504.
|
||
|
||
!!! note "Degradación puntual no relacionada, pendiente de vigilar"
|
||
Durante la ventana de validación se observó una ventana breve de
|
||
latencia alta (hasta 39s) y algunos `502`/`530`, coincidiendo con
|
||
una ejecución pesada de Gitea Actions (build/deploy de Medusa) en
|
||
el mismo host. Esto es contención de recursos local (CPU/IO del
|
||
host compitiendo entre el runner de Actions y el resto de los
|
||
servicios), **no relacionado al fix de protocolo del túnel** — no
|
||
se reabrió como parte de este incidente.
|
||
|
||
**Actualización 2026-08-15:** sí fue recurrente — ver
|
||
[contención de recursos entre Gitea y su runner](incidente-contencion-recursos-gitea-runner-2026-08.md)
|
||
para la causa raíz confirmada (ninguno de los dos contenedores
|
||
tiene límites de recursos reales) y la propuesta de fix.
|