Proyectos

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.

Docker · Traefik RTX 3070 · Ollama 12 containers 11 subdominios activos Self-hosted

// 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

Por qué

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.

Trade-off

Dos capas de routing. Deuda técnica intencional que se paga migrando servicio por servicio.

PostgreSQL compartido solo para servicios nuevos

Por qué

Tres instancias separadas consumirían ~900MB de RAM. Una instancia compartida con schemas separados: ~300MB. Gitea, Outline y GlitchTip comparten stack_postgres.

Trade-off

Sin aislamiento de permisos a nivel de BD. Mitigado con usuarios Postgres dedicados por schema.

Outline sobre Logseq

Por qué

Outline tiene API REST, permite colaboración y facilita sincronización desde el repo. Logseq es local-first con sync de pago.

Trade-off

Outline requiere PostgreSQL y Redis — dependencias que no son gratis en términos de RAM.

pgvector/pg16 sobre postgres:16-alpine

Por qué

La imagen oficial no incluye pgvector. La imagen de pgvector tiene la extensión preinstalada — sin compilarla en el init script.

Trade-off

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.