Proyecto 02 · Infraestructura self-hosted
Homelab
No es hobby. Es el laboratorio donde experimento con las herramientas que luego uso o enseño. 12 servicios en producción corriendo en mi propio servidor — sin depender de ningún servicio de terceros para ninguna de estas funciones.
// por qué
La razón principal
Necesitaba un entorno donde probar Ollama con hardware real antes de recomendar modelos locales a clientes o equipos. La GPU que corre los modelos es la misma que alimenta CertEngine. 83 tok/s con Qwen 2.5 7B — comparado con ~8 tok/s en CPU. Esa diferencia es la que hace que RAG sea una experiencia usable, no una demostración lenta.
El segundo motivo: no quiero depender de servicios externos para funciones críticas de mi flujo de trabajo. Cada servicio del homelab reemplaza una suscripción de pago o un tercero que tiene acceso a mis datos.
// arquitectura
Cómo se conecta todo
Internet
└── CloudFlared Tunnel
├── n8n.ericmartinezf.dev → n8n (directo)
├── ai.ericmartinezf.dev → OpenWebUI (directo)
├── ericmartinezf.dev → Landing page (directo)
└── Traefik (router HTTP interno)
├── git.ericmartinezf.dev → Gitea
├── notes.ericmartinezf.dev → Outline
├── vault.ericmartinezf.dev → Vaultwarden
├── status.ericmartinezf.dev → Uptime Kuma
├── logs.ericmartinezf.dev → Dozzle
├── docker.ericmartinezf.dev → Dockge
└── errors.ericmartinezf.dev → GlitchTip
Ollama (stack_net interno — sin ruta externa) Los servicios existentes (n8n, OpenWebUI, landing) se exponen directamente via CloudFlared. Traefik entra como router interno para los servicios nuevos — los existentes mantienen su ruta directa. Deuda de arquitectura intencional: se paga migrando servicio por servicio cuando hay tiempo.
// stack
Los 12 servicios — y por qué cada uno
| Servicio | Por qué este | Por qué no la alternativa cloud |
|---|---|---|
| Ollama + RTX 3070 | Inferencia local a 83 tok/s con Qwen 2.5 7B. El mismo motor que alimenta CertEngine. | OpenAI/Anthropic API: costo variable, latencia de red, los datos salen del servidor. |
| Gitea | Control de versiones privado para proyectos que no quiero en GitHub. | GitHub/GitLab: repositorios privados en servidores de terceros. |
| Vaultwarden | Gestión de contraseñas compatible con Bitwarden, self-hosted. | 1Password/Bitwarden cloud: suscripción mensual + credenciales en servidores externos. |
| Outline | Documentación con API REST y Google OAuth. | Notion/Confluence: notas de arquitectura en un servicio externo. |
| GlitchTip | Error tracking compatible con Sentry SDK. | Sentry cloud: eventos limitados en plan gratuito + datos de errores fuera del servidor. |
| Uptime Kuma | Monitoreo de los 12 servicios con alertas. | UptimeRobot: solo verifica que el puerto responde, no el estado interno. |
| Traefik | Reverse proxy con detección automática via labels Docker. | nginx manual: configuración estática por cada nuevo servicio. |
| n8n | Automatización de flujos entre servicios del homelab. | Zapier/Make: datos de automatización en servidores externos. |
CertEngine (cert.ericmartinezf.dev) es el container 13 — proyecto independiente que usa la misma infraestructura compartida (stack_postgres, stack_redis, stack_ollama).
// decisiones
4 decisiones con trade-off documentado
CloudFlared + Traefik coexistiendo, no Traefik reemplazando
CloudFlared ya exponía servicios existentes. Reemplazarlo hubiera requerido migrar cada uno con riesgo de downtime. Traefik entra como router interno para los servicios nuevos.
Dos capas de routing. Deuda técnica intencional que se paga migrando servicio por servicio.
PostgreSQL compartido solo para servicios nuevos
Tres instancias separadas consumirían ~900MB de RAM. Una instancia compartida con schemas separados: ~300MB. Gitea, Outline y GlitchTip comparten stack_postgres.
Sin aislamiento de permisos a nivel de BD. Mitigado con usuarios Postgres dedicados por schema.
Outline sobre Logseq
Outline tiene API REST, permite colaboración y facilita sincronización desde el repo. Logseq es local-first con sync de pago.
Outline requiere PostgreSQL y Redis — dependencias que no son gratis en términos de RAM.
pgvector/pg16 sobre postgres:16-alpine
La imagen oficial no incluye pgvector. La imagen de pgvector tiene la extensión preinstalada — sin compilarla en el init script.
Imagen más pesada. Vale para tener vector search disponible en cualquier BD del stack sin pasos adicionales.
El homelab es la base sobre la que corre CertEngine.