Reparto de infraestructura — Cloudflare · local · OCI free · Vercel · (HF puntual)

Fecha: 2026-09-22. Estado: decidido (Linode caído; ver 2026-09-22-linode-caido-permanentemente.md). Decisiones de esta sesión: engine → OCI free · radio → procesada local + servida por Vercel. (GCP queda solo para BigQuery; se descartó el e2-micro por RAM/egress.)

Regla de asignación

Cada tarea al host que domina su cuello de botella:

  • egress (sirve a usuarios) → Cloudflare o Vercel (según volumen; ver límites).
  • proceso always-on / cron / sidecars → OCI free (4 OCPU / 24 GB ARM).
  • GPU, cookies, datos privados, audio pesado → local.
  • picos de cómputo por lote → HF (no host fijo).

El reparto

TareaHoyDestinoPor qué
Engine core: capturar + exportar (cron */30, Python)Linode /opt/siloOCI freeVM always-on con RAM de sobra; egress no es problema (el engine entra, casi no emite)
RSSHub (Node + TWITTER_AUTH_TOKEN)Linode DockerOCI free (sidecar)el engine necesita localhost:1200
Estado silo.db (36 MB) + estado.jsondisco LinodeOCI + snapshot a R2SQLite local; R2 versiona con egress $0
Servir exports (export-editorial.json, RSS, home/feed)nginx LinodeCloudflare (Pages/Workers + R2)egress $0, global, cero servidor
Cron de consumidores (surtido, home)cron MacCloudflare Cron Triggersfree, sin Mac encendida
Radio (render + parrilla + subtítulos)Linode icecast/liquidsoaplocal (procesa) + Vercel (sirve)ver sección abajo
Paywall / browser (news-silo T2/T3)Maclocalcookies, sesión, privacidad
Extracción LLM (Ollama, exports + likes)GPU locallocal (base) + HF (picos)HF solo para la corrida de 111 chunks
Turismo RAG (estado_turismo/engine)CF WorkersCloudflare (ya está)no tocar
BigQuery Places / ocupaciónGCPGCP (BQ 1 TiB/mes free)ya vive ahí
Scrapers places (Apify/SerpApi/Booking)Mac + Vercellocal/Vercelcomo hoy

La radio sin icecast (procesa local, sirve Vercel)

El limón de la radio era icecast en vivo, que exige un host con ancho de banda. No hace falta: la parrilla ya es renderizada (ver 2026-09-06-radio-linode-es-subtitulos.md: gcloud TTS + push MP3, scripts surtido/scripts/{radio_cron,tanda_radio,radio_parrilla,radio_push}.sh). Lo único que hacía el Linode era reproducir. Eso se resuelve con archivos estáticos.

local (OCI o Mac)                         Vercel (estático)
  gcloud TTS + liquidsoap/ffmpeg   ──►    /radio/manana.mp3 + /radio/now.json + .vtt
  (procesa la parrilla del día)           (player con seek al minuto "en vivo")

Dos formas, de más simple a más “radio”:

  • MVP — un MP3 continuo por bloque + seek. Render 24 h (o por bloque) a un solo archivo; publicas un now.json con {archivo, offset_inicio}; el player hace un range request y arranca en el segundo que toca. Simple, sin HLS.
  • Mejor — HLS rodante. liquidsoap output.file.hls escribe .m3u8 + segmentos .aac/.ts + .vtt (subtítulos) y se suben a Vercel/R2. Suena como stream real. (verificar flags de output.file.hls en el liquidsoap instalado).

Bandwidth (esto manda): a 128 kbps ≈ 57.6 MB por hora por oyente. Vercel Hobby = 100 GB/mes (hard cap) → ~1,700 horas-oyente/mes (≈ 2–3 oyentes 24/7). MáS de eso → R2 (egress 20) o R2.

Límites reales de cada host (verificados 2026-09)

HostGratisEl catch
OCI free (ARM A1)4 OCPU / 24 GB RAM / 200 GB, always-oncupo por región; ARM (verificar imágenes Docker arm64)
Cloudflare Workers/Pages/R2Workers 100k req/día; R2 10 GB + egress $0; Pages ancho de banda ilimitadoCPU ms por request; no procesos largos
Vercel Hobby100 GB datos/mes, 1 M invocacioneshard cap, se pausa; no comercial
HF Jobspor segundo; Pro da $2/mes créditocold start; sin sidecar (RSSHub no cabe)
GCP freeBQ 1 TiB/mes; e2-micro 1 VMe2-micro: 1 GB RAM / 1 GB egress → descartado como host

Versión más chica que funciona

  1. OCI free: engine + RSSHub + (opcional) el render de radio.
  2. Cloudflare: servir exports/RSS/archivos (R2) + cron.
  3. Vercel: la radio (estático) y surtido.
  4. Local: GPU, cookies/privacidad.
  5. HF: solo la corrida puntual de extracción.

Pendientes

  • Fase 0: provisionar la VM OCI (Ubuntu, Docker, Python) y correr capturar una vez midiendo RAM y tiempo. Artefacto: export-editorial.json servido por CF.
  • Portar deploy.sh/run.sh de nef-silo: SILO_HOST=... (ya no linode_root).
  • Decidir si el render de radio corre en OCI o en la máquina local con GPU.
  • Confirmar cupo/región del OCI free y arquitectura arm64 de las imágenes.