⌘J
En esta página 7

Engineering / Infraestructura y deploy

Infraestructura y deploy

La arquitectura de infra de Axel (Cloudflare edge, Laravel Cloud, el VPS del Optimizer) y la estrategia de costos y salida que evita el lock-in.

Diseño aprobado, aún sin deploy. Esta es la arquitectura de infra decidida, no un entorno ya montado (el repo platform — con F0–F2 mergeadas — no tiene deploy productivo todavía). El primer deploy tiene además dos validaciones pendientes del gate de F2: el pooler transaccional y la provisión del rol de RLS (ver Multi-tenancy). La única pieza realmente en producción hoy es esta documentación.

La infra se repensó de cero el 2-jul-2026 y es la fuente única vigente (reemplaza el plan anterior). Laravel Cloud es la decisión válida para el MVP, con trigger de reevaluación a escala. Development es local (ver Setup); esta página cubre staging y producción.

Los tres principios que ordenan toda la infra:

  1. El recurso escaso son las horas del CTO, no los dólares. La infra se optimiza por tiempo del cuello de review/decisión, no por el menor costo.
  2. Ser dueño del software, no del metal. El lock-in a evitar es el de producto; el cómputo gestionado detrás de un git push es commodity.
  3. Cloudflare es un activo gratis ya disponible. Todo lo estático y el edge salen $0.

Arquitectura por capas

CLOUDFLARE (edge, $0) ── DNS axel.legal · certs · WAF/DDoS · Turnstile
│                        docs + vision + landing (Pages, estático)
│                        R2 (backups + PDFs firmados, S3-compatible)
│                        Tunnel — Laravel Cloud ↔ Optimizer, sin puertos públicos

LARAVEL CLOUD ────────── AxelOps · platform: staging → MVP privado → público
│  (AWS us-east-1)       (environments del mismo lugar, solo se sube de tier)
│           │
│           └──── CF Tunnel ────┐
│                                ▼
VPS OPTIMIZER (Hetzner ─ compose Optimizer + Redis · Docker crudo
 Ashburn, VA)            gestionado por el skill de Docker

GITHUB ($0) ──────────── código · PRs · CI · GitHub Projects (tracker)
RESEND ($0→) ─────────── mail transaccional

Staging → MVP privado → producción pública son environments del mismo Laravel Cloud: sin migración de plataforma entre etapas, ni siquiera al entrar PII real ni al abrir al público. Eso evita migrar justo cuando el riesgo es más alto.

Las piezas

Laravel Cloud

platform + AxelOps. Corre en AWS us-east-1 (Virginia). Postgres serverless (Neon por debajo, PG 18) con shared schema + tenant_id + RLS.

VPS del Optimizer

El único componente Docker del sistema. Alberga los dos Optimizers del PSCE (SignBox + One-Shot) + Redis, en Docker crudo sin panel. Recibe hashes, retiene PDFs firmados (disco grande).

Cloudflare (edge)

DNS, certs, WAF/DDoS, Turnstile, R2 (backups + PDFs), Pages para los estáticos, y el Tunnel que conecta Laravel Cloud con el Optimizer.

Resend + GitHub

Resend para mail transaccional (invitaciones, notificaciones). GitHub para código, PRs, CI y el tracker (GitHub Projects, org heyaxel).

Restricción de región

El VPS del Optimizer debe ir en Hetzner Ashburn, VA

Laravel Cloud corre en AWS us-east-1 (Virginia). El VPS del Optimizer debe ir en Hetzner Ashburn, VA (misma metro area, alta densidad de peering), no en otra región (Falkenstein saltaría a ~90-120ms transatlántico). Con Ashburn: ~1-5ms Laravel Cloud ↔ VPS, compatible con el patrón de polling de UANATACA. Es una decisión, no un default.

Certificados

Con dominio único (0.10), la tenancy no requiere wildcard: alcanza con los subdominios fijos (app, staging). La regla crítica con Cloudflare como DNS, para los certs de Laravel Cloud vía DCV delegation:

Los registros _acme-challenge van DNS-only (nube gris). Si se proxian, se bloquea la emisión de certs. La receta: los hosts de app DNS-only → Laravel Cloud (que sirve TLS y trae su propia mitigación DDoS), y CF proxy solo para los estáticos (docs, vision, landing). Si algún día entran subdominios por región (#192), ahí se evalúa wildcard; hoy no hace falta.

Estrategia de costos

Sin cifras aquí: la política, en tres capas.

Guardrails (día 0)

Spending limit por environment desde el primer deploy (Laravel Cloud pausa compute al tocar el techo) + alerts. Región única. Revisión semanal del usage dashboard como parte de la higiene de cierre de semana.

Defaults frugales

Lo barato es el default, no el ajuste: cache/sessions/queues en la DB (driver database), compute en el Flex más pequeño, estáticos NUNCA en Laravel Cloud (a CF Pages), staging y previews sin scheduler/workers (que duerman de verdad).

Palancas listas, no activadas. Un tick externo para el scheduler (cron trigger de Cloudflare Workers en vez de schedule:run 24/7), réplicas con techo bajo, y sleep nocturno de la DB de prod quedan documentados para activarse cuando un número real los justifique, no antes. Managed Queues (sobre SQS, scale-to-zero) sobre un worker 24/7: casi no pesan al volumen de Axel. El principio rector: optimizar con la factura en la mano, no con miedo.

Estrategia de salida

Anti-lock-in: .env + pg_dump + R2

El exit de Laravel Cloud es .env + pg_dump + los deploy scripts que viven en el repo: horas, no semanas. Backups y PDFs en R2 (API S3 neutral) nunca quedan presos. La decisión de hosting se reabre solo si el costo supera un umbral sostenido o si el volumen post-PMF hace obvia la matemática de un VPS. Antes de eso, no se toca: cada re-litigación cuesta más que la diferencia de precio.

Mapa de subdominios

Dominio único (decisión 0.10, cerrada 16-jul). No hay subdominio por tenant: todos los tenants viven bajo app.axel.legal y se resuelven por sesión. Los subdominios de abajo son fijos (no wildcard); no hace falta aprovisionar wildcard DNS ni certificado *.axel.legal. Ver Decisiones → 0.10. Los subdominios por región (data-residency multipaís) son otra decisión (#192), todavía no activa.

DominioQué sirve
app.axel.legalApp (login, selección de empresa, todos los tenants)
staging.axel.legalStaging
optimizer.axel.internalOptimizer (privado, nunca público)
handbook.axel.legalHub de documentación (Astro, CF Pages)
vision.axel.legalSitio de visión

El VPS del Optimizer no se paga hasta que la firma (#3) llegue a prod: el sandbox hosted de UANATACA cubre toda la fase de integración sin VPS. Ver Firma certificada para el flujo que corre sobre esta infra.