pgbouncer incompatible con Dokploy networking (Swarm)
pgbouncer incompatible con Dokploy networking
Cuándo
Febrero 2026, durante la incorporación de pgbouncer al stack de producción como connection pooler entre Django y PostgreSQL. Servicio añadido a compose.prod.yml, Dokploy lo desplegó al detectar el push.
Síntomas
Contenedor web arrancaba sin errores visibles pero fallaba al resolver hostname pgbouncer dentro de la red Docker. Django lanzaba django.db.utils.OperationalError: could not translate host name "pgbouncer" en cada request, dejando la aplicación inaccesible. Dokploy marcaba web como unhealthy y healthcheck de pgbouncer pasaba correctamente, dificultando el diagnóstico.
Causa raíz
Dokploy gestiona despliegues dentro de una red Docker overlay propia, dokploy-network. Contenedores que Dokploy arranca pertenecen a esa red y resuelven DNS únicamente dentro de ella. pgbouncer fue definido en compose.prod.yml perteneciendo a la red interna del proyecto (crearack_internal), red bridge separada. Resultado: contenedor web — lanzado por Dokploy en dokploy-network — no tenía visibilidad DNS de pgbouncer en crearack_internal. Las 2 redes son disjuntas y Docker no enruta entre ellas automáticamente.
Para hacer pgbouncer accesible desde Dokploy, habría que añadirlo como servicio Dokploy independiente con acceso explícito a dokploy-network, o conectar manualmente el contenedor a ambas redes tras cada deploy (frágil, no sobrevive redeployments).
Fix aplicado
Revertir configuración de Django para apuntar directamente a BD: POSTGRES_HOST=db, POSTGRES_PORT=5432. PostgreSQL configurado con max_connections=500 para absorber carga sin pooler intermedio. Servicio pgbouncer queda definido en compose.prod.yml pero inactivo — web service lo ignora. Solución intencional y documentada como estado permanente hasta encontrar arquitectura compatible con el modelo de red de Dokploy.
Lecciones
- Dokploy aísla contenedores en
dokploy-network: cualquier servicio auxiliar (pgbouncer, redis propio, etc.) no perteneciente a esa red no es resolvible por DNS desde la app. - Añadir un servicio a
compose.prod.ymlno garantiza accesibilidad — depende de en qué redes lo registra Dokploy. - Incompatibilidad no obvia: pgbouncer arranca sano, healthcheck pasa, pero nadie puede conectarse desde fuera de su red.
Preventivos futuros
- Antes de añadir servicio intermediario (proxy, pooler, cache), verificar en qué red lo coloca Dokploy y si contenedor web puede resolverlo por nombre.
- Evaluar si pgbouncer puede registrarse como proyecto Compose separado en Dokploy para heredar
dokploy-network. - Alternativamente, PgBouncer como sidecar dentro del mismo servicio web, evitando el problema de red.
- Documentar estado actual (
POSTGRES_HOST=db) como decisión explícita encompose.prod.ymlpara evitar que futuros cambios lo reviertan sin contexto.
Véase también
- [[decision—20260315—postgres-18-pgbouncer]]
- [[decision—20251201—dokploy-vs-kubernetes]]