Ir al contenido

Conceptos 04 - Errores comunes de redes y troubleshooting

Problemas frecuentes de conectividad entre servicios en Docker Compose, sus causas y soluciones. Recorra cada problema para ver el diagnóstico completo.

  • 8 problemas frecuentes
  • 9 elementos interactivos
  • Autoevaluación final

Concepto 1 de 8

Uso incorrecto de localhost

Connection refused al intentar conectarse a otro servicio mediante localhost.

Causa. Dentro de un contenedor, localhost hace referencia exclusivamente al propio contenedor. No corresponde a otro servicio de la aplicación.

DATABASE_URL=postgresql://user:pass@localhost:5432/mydb

Cambia el host de la cadena de conexión y observa a dónde llega la conexión.

DATABASE_URL=postgresql://user:pass@localhost:5432/mydb

Connection refusedlocalhost es la interfaz de loopback del propio contenedor web. La conexión nunca sale de web, y ahí nada escucha en el puerto 5432.

Concepto 2 de 8

Publicación innecesaria de puertos

La base de datos queda accesible desde el host sin requerirlo o se presentan colisiones de puertos.

Causa. Se ha publicado un puerto, por ejemplo 5432:5432, en un servicio que solo debe ser consumido por otros contenedores.

db:
image: postgres:16
ports:
- "5432:5432" # expone al host sin necesidad

Concepto 3 de 8

Asumir que publicar un puerto habilita comunicación interna

Un contenedor no logra conectarse a otro, aunque el servicio destino tenga puertos publicados.

Causa. La publicación de puertos habilita acceso desde el host, no garantiza conectividad entre contenedores. Si los servicios no comparten una red, no podrán comunicarse entre sí.

Solución. Verifique que ambos servicios estén conectados a una misma red de Docker.

Ventana de terminal
# Verificar redes de cada contenedor
$ docker network inspect mi-proyecto_default

Publica el puerto de db y quita la red compartida: el acceso desde el host funciona, pero web sigue sin llegar a db.

  • Contenedor → contenedorweb → postgresql://…@db:5432/mydb
  • Host → contenedorpsql -h localhost -p 5432 -U user mydb

Concepto 4 de 8

Servicios sin red compartida

Un servicio no logra resolver el nombre de otro servicio.

Causa. En una configuración con redes explícitas, los servicios que deben comunicarse no comparten al menos una red.

Ventana de terminal
# Verificar resolución DNS desde un contenedor
$ docker compose exec web getent hosts db
# Si falla: los servicios no comparten red

Concepto 5 de 8

Nombre de servicio incorrecto

Errores de resolución DNS como Name does not resolve o fallos de conexión.

Causa. La cadena de conexión utiliza un nombre que no coincide con la clave del servicio en compose.yml. Errores frecuentes: usar postgres cuando el servicio se llama db, utilizar container_name en lugar del nombre del servicio, o errores tipográficos.

DATABASE_URL=postgresql://user:pass@postgres:5432/mydb

Concepto 6 de 8

Colisión de puertos en el host

Error al iniciar un servicio porque el puerto ya está asignado.

Bind for 0.0.0.0:80 failed: port is already allocated

Causa. Otro proceso del host, o de otro proyecto Compose, ya utiliza ese puerto.

# Identificar el proceso
$ sudo lsof -i :80
$ ss -tlnp | grep :80
# Cambiar el puerto del host en compose.yml
ports:
- "8080:80" # usar 8080 en el host

Concepto 7 de 8

Servicio que inicia, pero aún no está disponible

Fallos intermitentes al conectarse a la base de datos durante el arranque. Funciona tras un reinicio manual.

Causa. El contenedor de base de datos ha sido iniciado, pero el motor aún se encuentra en proceso de inicialización. depends_on sin condiciones adicionales solo establece un orden de arranque, pero no garantiza que el servicio esté listo para aceptar conexiones.

Solución. Utilice depends_on con condition: service_healthy y defina un healthcheck en el servicio de base de datos. Como complemento, implemente lógica de reintentos en la aplicación.

web:
depends_on:
db:
condition: service_healthy
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 3s
retries: 5

Compara el arranque con cada configuración de depends_on.

web:
  depends_on:
    - db
db
detenido
web
detenido
$ docker compose up

Elige una configuración y ejecuta docker compose up.

Los tiempos son ilustrativos.

Concepto 8 de 8

Dependencia de direcciones IP efímeras

La aplicación funciona inicialmente pero pierde conectividad después de recrear los contenedores.

Causa. La cadena de conexión depende de una dirección IP fija, por ejemplo 172.18.0.3, que deja de ser válida cuando el contenedor es recreado.

Solución. Sustituya la dirección IP por el nombre del servicio. Docker actualiza automáticamente la asociación entre nombre y dirección IP mediante su mecanismo de resolución DNS interna.

DATABASE_URL=postgresql://user:pass@172.18.0.3:5432/mydb

Recrea el contenedor db y observa qué cadena de conexión sigue funcionando.

Contenedormi-proyecto-db-1IP actual172.18.0.3Recreaciones0
docker compose up -d --force-recreate db
  • Con IP fijapostgresql://user:pass@172.18.0.3:5432/mydbConecta: la IP coincide con la de db.
  • Con nombre de serviciopostgresql://user:pass@db:5432/mydbConecta: db resuelve a 172.18.0.3.

Las direcciones que aparecen al recrear son ilustrativas. Docker puede asignar otra IP cada vez; lo que no garantiza es que se conserve.

Autoevaluación

Comprueba lo que aprendiste

Cinco preguntas rápidas para verificar las ideas clave de la lectura. Cada respuesta incluye una explicación.

  1. 1La API usa localhost como host en su cadena de conexión hacia la base de datos y recibe Connection refused. ¿Por qué?
  2. 2db publica 5432:5432, pero web no logra conectarse a db. ¿Qué conviene revisar?
  3. 3El servicio se define como db y la aplicación usa el host postgres. ¿Qué error es esperable?
  4. 4¿Qué garantiza depends_on sin condiciones adicionales?
  5. 5La aplicación deja de conectarse a la base de datos después de recrear los contenedores. ¿Cuál es la causa más probable?

0/5 respuestas correctas