Docker Networking es el sistema que permite que dos o más contenedores se comuniquen entre sí como si estuvieran en la misma red privada.
El problema que resuelve Docker Networking
Imagina que trabajas en el equipo de tecnología de Liverpool. Tienes una aplicación web que muestra el catálogo de productos y una base de datos que guarda el inventario. Si ambas corren en contenedores separados, necesitan "hablar" entre sí. Sin una red en común, eso no es posible.
En la lección anterior aprendiste a persistir datos con volúmenes. Ahora el siguiente paso es conectar los servicios que usan esos datos. Docker Networking es exactamente la herramienta para eso.
Sin redes configuradas, tus contenedores son islas. Con redes, se convierten en un equipo.
El modelo de redes en Docker
Docker usa un concepto llamado red de contenedores. Cada red es un canal privado donde los contenedores inscritos pueden encontrarse por nombre, no por dirección IP.
Esto es importante: en lugar de escribir http://192.168.1.45:5432, puedes escribir http://base_de_datos:5432. Docker resuelve el nombre automáticamente. A esto se le llama resolución DNS interna.
Existen tres tipos de red principales en Docker:
| Tipo | ¿Qué hace? | ¿Cuándo usarlo? |
|---|---|---|
bridge |
Conecta contenedores en la misma máquina | Desarrollo local y producción simple |
host |
El contenedor usa la red del sistema operativo | Casos avanzados de rendimiento |
none |
El contenedor no tiene red | Tareas de procesamiento aislado |
Para el 90% de los proyectos, usarás redes de tipo bridge. Es el tipo predeterminado y el más seguro para empezar.
La red bridge predeterminada y sus límites
Cuando ejecutas docker run sin especificar red, Docker conecta el contenedor a una red bridge predeterminada llamada bridge. Suena conveniente, pero tiene un problema grave: los contenedores en esa red no se encuentran por nombre.
Ejecutas esto:
docker run -d --name mi_app nginx
docker run -d --name mi_db postgres
Ambos están en la red bridge predeterminada. Pero si mi_app intenta conectarse a mi_db por nombre, falla. Necesita la IP exacta, que cambia cada vez que reinicias el contenedor.
Esa fragilidad es el motivo por el que debes crear tus propias redes.
Cómo crear una red personalizada
El sistema que vas a aprender se llama Red Nombrada Personalizada. Funciona así:
Paso 1: Crea la red con un nombre descriptivo.
docker network create red_liverpool
Docker responde con un ID largo. Eso confirma que la red existe.
Paso 2: Arranca tus contenedores conectándolos a esa red.
docker run -d \
--name catalogo_app \
--network red_liverpool \
-p 8080:80 \
nginx
docker run -d \
--name catalogo_db \
--network red_liverpool \
-e POSTGRES_PASSWORD=secreto123 \
postgres
Paso 3: Verifica que los dos contenedores están en la misma red.
docker network inspect red_liverpool
Verás una sección Containers con ambos nombres listados. Si están ahí, ya se pueden comunicar.
Ejemplo práctico: app web + base de datos
Supón que desarrollas un sistema de seguimiento de pedidos para una empresa de logística inspirada en FEMSA. Tienes dos servicios:
pedidos_api: una app en Python que expone una API REST.pedidos_db: una base de datos PostgreSQL que guarda los pedidos.
Así los conectas:
# Crear la red
docker network create red_pedidos_femsa
# Iniciar la base de datos
docker run -d \
--name pedidos_db \
--network red_pedidos_femsa \
-e POSTGRES_USER=admin \
-e POSTGRES_PASSWORD=clave_segura \
-e POSTGRES_DB=pedidos \
postgres:15
# Iniciar la API
docker run -d \
--name pedidos_api \
--network red_pedidos_femsa \
-p 5000:5000 \
-e DATABASE_URL=postgresql://admin:clave_segura@pedidos_db:5432/pedidos \
mi_imagen_api
Observa la variable DATABASE_URL. En lugar de una IP, usa el nombre del contenedor pedidos_db. Docker lo traduce a la IP correcta en tiempo real. Si reinicias la base de datos y cambia su IP interna, la app no se rompe porque sigue usando el nombre.
Docker Compose y las redes automáticas
Escribir todos esos comandos manualmente es tedioso. Docker Compose simplifica todo esto con una sola instrucción.
Cuando defines servicios en un archivo docker-compose.yml, Compose crea automáticamente una red compartida para todos ellos. Todos los servicios del mismo archivo ya se pueden encontrar por nombre sin configuración extra.
services:
app:
image: mi_imagen_api
ports:
- "5000:5000"
environment:
- DATABASE_URL=postgresql://admin:clave@base_datos:5432/pedidos
depends_on:
- base_datos
base_datos:
image: postgres:15
environment:
- POSTGRES_USER=admin
- POSTGRES_PASSWORD=clave
- POSTGRES_DB=pedidos
volumes:
- datos_pedidos:/var/lib/postgresql/data
volumes:
datos_pedidos:
Aquí, app se conecta a base_datos usando el nombre base_datos directamente. Compose maneja la red por debajo sin que tú escribas nada adicional.
Redes personalizadas en Docker Compose
A veces necesitas más control. Por ejemplo, si tienes tres servicios y quieres que solo dos de ellos se comuniquen entre sí, puedes definir redes explícitas:
services:
frontend:
image: nginx
networks:
- red_publica
backend:
image: mi_api
networks:
- red_publica
- red_privada
base_datos:
image: postgres
networks:
- red_privada
networks:
red_publica:
red_privada:
En este esquema, frontend puede hablar con backend, pero nunca puede alcanzar directamente a base_datos. Eso agrega una capa de seguridad real. La base de datos queda aislada del exterior.
Este patrón es muy usado en aplicaciones de Bimbo o Mercado Libre donde la seguridad de los datos es crítica.
Comandos esenciales para gestionar redes
Estos son los comandos que usarás con más frecuencia:
# Ver todas las redes existentes
docker network ls
# Inspeccionar una red y ver qué contenedores tiene
docker network inspect nombre_red
# Conectar un contenedor ya corriendo a una red
docker network connect nombre_red nombre_contenedor
# Desconectar un contenedor de una red
docker network disconnect nombre_red nombre_contenedor
# Eliminar una red (debe estar vacía)
docker network rm nombre_red
# Eliminar todas las redes que no están en uso
docker network prune
Errores comunes al trabajar con redes
Error 1: Usar la red bridge predeterminada. Los contenedores ahí no se resuelven por nombre. Siempre crea una red personalizada.
Error 2: Escribir la IP del contenedor directamente. Las IPs internas de Docker cambian. Usa siempre el nombre del contenedor como hostname.
Error 3: Olvidar el flag --network al arrancar un contenedor. Si lo olvidas, el contenedor queda en la red predeterminada y no podrá comunicarse con tu red personalizada. Verifica siempre con docker network inspect.
Error 4: Publicar un puerto de la base de datos hacia el exterior. Si haces -p 5432:5432 en tu base de datos, cualquier persona en internet podría intentar conectarse. Las bases de datos solo deben comunicarse a través de la red interna de Docker, no por puertos públicos.
Error 5: No usar depends_on en Compose. Si tu API arranca antes que la base de datos, fallará al intentar conectarse. El campo depends_on le indica a Compose el orden correcto de inicio.
Verificar que la comunicación funciona
Puedes probar la conexión entre contenedores entrando a uno de ellos y usando ping o curl:
# Entrar al contenedor de la app
docker exec -it pedidos_api sh
# Dentro del contenedor, hacer ping a la base de datos por nombre
ping pedidos_db
Si ves respuesta, la red funciona correctamente. Si no hay respuesta, revisa que ambos contenedores estén en la misma red con docker network inspect.
La regla de oro del networking en Docker es esta: nunca uses IPs, siempre usa nombres, y siempre usa redes personalizadas.