Redes Docker del Ecosistema Timeliber
Cuadrante 04_EXPLANATION — qué redes existen, quién las usa, por qué. Última actualización: 2026-05-15 — Sprint Doc-3 (drift corregido contra
infra/docker-compose.ymlreal).
1. ¿Qué es una red Docker y por qué existe?
Una red Docker es una red privada lógica dentro del servidor. Los containers en la misma red pueden hablarse por nombre. Los containers en redes diferentes están aislados — aunque corran en el mismo host.
Por qué importa: la base de datos NUNCA debe estar en la misma red que el tráfico de internet. Si un atacante accede a la capa pública, el aislamiento de redes impide alcanzar PostgreSQL.
2. Las DOS redes del ecosistema
Ambas son externas (creadas antes del primer docker compose up) para evitar colisiones de naming:
2.1 proxy-net — Red pública
- Quiénes están: Traefik (corre fuera del workspace, ver §4) + servicios que necesitan exposición pública vía HTTPS (frontends de apps, APIs públicas).
- Para qué: Traefik solo enruta HTTPS a containers que pertenezcan a esta red.
- Analogía: la recepción del hotel — todo lo que viene de internet pasa por aquí.
2.2 timeliber-net — Red interna
- Quiénes están: Postgres, Redis, Qdrant, n8n, Evolution, y todos los backends de apps (Travel, Gastro, AI Orchestrator, RAG).
- Para qué: comunicación stateless entre backends y datos persistentes, sin exposición externa.
- Analogía: la cocina del hotel — solo personal autorizado.
⚠️ Nota histórica: en versiones antiguas la red interna se llamaba
timeliber-travel-backend_timeliber-network. La denominación actual canónica estimeliber-net(configurable porINFRA_NETWORK_NAMEeninfra/.env). Si encuentras la denominación antigua en código viejo, actualizar.
3. Tabla de servicios → redes (validada contra infra/docker-compose.yml real)
Servicios en infra/docker-compose.yml
| Container (nombre real) | proxy-net |
timeliber-net |
Motivo |
|---|---|---|---|
timeliber-postgres |
❌ | ✅ | DB aislada, jamás expuesta a internet |
timeliber-redis |
❌ | ✅ | Cache aislado |
timeliber-qdrant |
✅ | ✅ | Dashboard expuesto a HTTPS + escritura local de vectores |
timeliber-n8n-prod |
✅ | ✅ | Webhooks WhatsApp + guarda flujos en PostgreSQL |
timeliber-evolution-prod |
✅ | ✅ | Gateway WhatsApp + sesiones en evolution_db + Redis |
Servicios externos (NO en infra/docker-compose.yml)
| Container | Ubicación | Redes |
|---|---|---|
| Traefik | ~/traefik/docker-compose.yml (fuera del workspace) |
proxy-net (solo) |
Servicios de aplicaciones (en apps/*/)
| Container | proxy-net |
timeliber-net |
Motivo |
|---|---|---|---|
travel-backend |
✅ | ✅ | API que lee/escribe travel_db |
travel-frontend |
✅ | ❌ | Solo sirve HTML |
gastro-backend |
✅ | ✅ | API que lee/escribe gastro_db + cache Redis |
gastro-admin |
✅ | ❌ | SPA estática (Vite build → nginx en contenedor) |
gastro-menu |
✅ | ❌ | Next.js standalone |
ai-orchestrator |
✅ (via Traefik si público) | ✅ | LangGraph + checkpoints Redis + Travel HTTP |
rag-studio |
⚠️ pendiente compose | ✅ | Cliente Qdrant + LightRAG local |
main-backend |
✅ | ❌ | Solo SMTP + leads (sin BD operativa) |
main-frontend |
✅ | ❌ | Next.js SSR |
omnicortex-frontend |
✅ | red propia omnicortex-internal |
Same-Origin Always (ver OmniCortex ARCHITECTURE) |
omnicortex-backend |
❌ | red propia omnicortex-internal |
Nunca expuesto directo a internet |
4. Traefik vive fuera del workspace
Traefik no está en infra/docker-compose.yml. La carpeta infra/traefik/ existe pero está vacía (legacy — registrado en infra/TECH_DEBT.md como INFRA-DOC3).
Ubicación real: ~/traefik/ con su propio docker-compose.yml y .env:
~/traefik/
├── docker-compose.yml ← Servicio Traefik v2.11 (NO commiteado al monorepo)
├── .env ← TRAEFIK_DASHBOARD_HASH, ACME_EMAIL
├── traefik.yml ← Config estática (entrypoints, certresolvers)
└── acme.json ← Certificados Let's Encrypt persistentes (chmod 600)
Por qué fuera del workspace: Traefik es un servicio compartido del servidor (puede atender múltiples monorepos en el mismo host). Si se incluyera en el workspace, no podría reutilizarse para otros proyectos.
Las labels Traefik (traefik.enable=true, etc.) sí viven en cada docker-compose.yml de los servicios expuestos — eso es service discovery, no contraría que Traefik viva externo.
Detalle del flujo de una petición → traefik-proxy.md.
5. Resolución DNS interna
Dentro de una red Docker, los containers se llaman entre sí por nombre, no por IP. Docker resuelve por DNS interno; las IPs flotantes cambian al recrear contenedores.
# travel_backend se conecta a Postgres
# En su .env:
POSTGRES_HOST=timeliber-postgres # ← nombre real del container (ver docker-compose.yml de infra)
# Docker, vía DNS interno en timeliber-net, lo resuelve automáticamente.
Regla absoluta: NUNCA hardcodear IPs en configuración. Siempre usar el nombre del container.
6. Diagnóstico rápido
# ¿En qué redes está un container?
docker inspect timeliber-postgres | jq '.[0].NetworkSettings.Networks | keys'
# ¿Un container alcanza otro por nombre?
docker exec timeliber-n8n-prod ping -c 2 timeliber-postgres
# Conectar manualmente un container a una red (sin recrearlo)
docker network connect timeliber-net <nombre_container>
# Listar containers en una red
docker network inspect timeliber-net | jq '.[0].Containers | to_entries[] | .value.Name'
# Forzar a Traefik a re-leer service discovery
docker restart traefik # (corre en ~/traefik/, no aquí)
7. Dónde vive cada .env
~/traefik/.env ← Traefik (dashboard password, ACME)
~/software/timeliber-workspace/infra/.env ← Infra compartida (Postgres, Redis, Qdrant, n8n, Evolution)
~/software/timeliber-workspace/apps/main/{backend,frontend}/.env
~/software/timeliber-workspace/apps/travel/{backend,frontend}/.env
~/software/timeliber-workspace/apps/gastro/{backend,frontend}/.env
~/software/timeliber-workspace/apps/ai-orchestrator/.env
~/software/timeliber-workspace/apps/tools/rag/.env
~/software/timeliber-workspace/apps/visionArtificial/OmniCortex/.env.local
Regla absoluta: ningún .env real va a Git. Todos están en .gitignore. Si por error subes credenciales reales → rotar TODAS las contraseñas inmediatamente y de manera transversal.
8. Lección aprendida (2026-03-31) — vigente
Incidente: evolution-api y n8n arrancaron solo en proxy-net. No podían escribir a timeliber-postgres ni a timeliber-redis porque éstos viven en timeliber-net.
Síntoma operativo: webhooks de WhatsApp llegaban (Evolution responde HTTP), pero las sesiones no se persistían y los flujos de n8n fallaban silenciosamente al guardar.
Solución aplicada: ambos servicios fueron añadidos a las dos redes:
services:
n8n:
networks: [timeliber-net, proxy-net] # ← AMBAS
evolution-api:
networks: [timeliber-net, proxy-net] # ← AMBAS
Esta corrección ya está fijada permanentemente en infra/docker-compose.yml desde abril 2026.
Costo del incidente: 2 horas de downtime productivo. Regla derivada:
Cualquier servicio que reciba webhooks o tráfico HTTP de internet Y necesite persistencia, debe estar en
proxy-net+timeliber-net. Validar antes del deploy.
9. Referencias
- traefik-proxy.md — flujo de una petición HTTP
infra/docker-compose.yml— fuente de verdad de los serviciosinfra/.env.example— variables de entorno requeridas- Runbook maestro deployment
infra/TECH_DEBT.md— deuda técnica registrada
Drift corregido vs infra/docker-compose.yml real en Sprint Doc-3 (2026-05-15). Si encuentras drift nuevo → registrar en TECH_DEBT.md.