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.
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/mydbDATABASE_URL=postgresql://user:pass@db:5432/mydbCambia 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 necesidaddb: image: postgres:16 # sin ports: solo accesible internamenteConcepto 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.
# Verificar redes de cada contenedor$ docker network inspect mi-proyecto_defaultPublica el puerto de db y quita la red compartida: el acceso desde el host funciona, pero web sigue sin llegar a db.
- Contenedor → contenedor
web → postgresql://…@db:5432/mydb - Host → contenedor
psql -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.
# Verificar resolución DNS desde un contenedor$ docker compose exec web getent hosts db# Si falla: los servicios no comparten redConcepto 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/mydbNombre correcto (coincide con la clave del servicio):
DATABASE_URL=postgresql://user:pass@db:5432/mydb
# En compose.yml el servicio se define como:services: db: # ← este es el hostname image: postgres:16Concepto 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 allocatedCausa. 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.ymlports: - "8080:80" # usar 8080 en el hostConcepto 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: 5Compara el arranque con cada configuración de depends_on.
web:
depends_on:
- db- db
- detenido
- web
- detenido
$ docker compose upElige 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/mydbDATABASE_URL=postgresql://user:pass@db:5432/mydbRecrea el contenedor db y observa qué cadena de conexión sigue funcionando.
mi-proyecto-db-1IP actual172.18.0.3Recreaciones0docker compose up -d --force-recreate db- Con IP fija
postgresql://user:pass@172.18.0.3:5432/mydbConecta: la IP coincide con la de db. - Con nombre de servicio
postgresql://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.
0/5 respuestas correctas