8. Redes en Docker

Las aplicaciones modernas rara vez consisten en un único componente. Lo más común es tener una arquitectura de microservicios, donde un frontend, un backend y una base de datos se ejecutan en contenedores separados. Para que esto funcione, necesitan comunicarse entre sí. Aquí es donde entra en juego el sistema de redes de Docker.

Redes por defecto

Cuando instalas Docker, se crean tres redes automáticamente. Puedes verlas con `docker network ls`.

  • bridge: Es la red por defecto en la que se inician los contenedores si no se especifica otra. Los contenedores en esta red pueden comunicarse entre sí usando sus direcciones IP internas, pero no por su nombre. No es la opción recomendada para producción.
  • host: El contenedor no obtiene su propia pila de red, sino que comparte la del host. Si ejecutas un servidor web en el puerto 80 dentro del contenedor, este estará directamente accesible en el puerto 80 del host. Es rápido, pero pierdes el aislamiento de red.
  • none: El contenedor queda completamente aislado de la red. No tiene acceso a otros contenedores ni a internet. Útil para trabajos que no requieren ninguna conectividad.

Redes personalizadas (Custom Bridge Networks)

La forma recomendada de gestionar la comunicación entre contenedores es crear tus propias redes de tipo `bridge`. Ofrecen varias ventajas sobre la red `bridge` por defecto:

  • Aislamiento mejorado: Solo los contenedores que conectes explícitamente a tu red podrán comunicarse entre sí.
  • Resolución de nombres interna (DNS): Esta es la gran ventaja. Los contenedores pueden descubrirse y comunicarse usando su nombre de contenedor como si fuera un nombre de dominio (DNS). No necesitas preocuparte por las direcciones IP.
  • Configuración dinámica: Puedes conectar y desconectar contenedores de una red en caliente, sin necesidad de reiniciarlos.

Crear y gestionar redes personalizadas

La gestión se realiza con el subcomando `docker network`.

# Crear una nueva red de tipo bridge
docker network create mi-red-app

# Listar las redes disponibles
docker network ls

# Inspeccionar una red para ver qué contenedores están conectados
docker network inspect mi-red-app

# Eliminar una red (primero debes desconectar y detener los contenedores)
docker network rm mi-red-app

Ejemplo: Conectar un Backend a una Base de Datos

Vamos a simular un escenario real: un contenedor con una aplicación (backend) que necesita conectarse a un contenedor de base de datos (PostgreSQL).

Paso 1: Crear la red

Primero, creamos una red aislada para nuestra aplicación.

docker network create app-network

Paso 2: Lanzar el contenedor de la base de datos

Lanzamos un contenedor de PostgreSQL, le damos un nombre y lo conectamos a nuestra red.

docker run -d --name mi-postgres-db --network app-network -e POSTGRES_PASSWORD=mi-clave-secreta postgres:14-alpine
  • --name mi-postgres-db: Le damos un nombre que usaremos para la conexión.
  • --network app-network: Lo conectamos a la red que creamos.

Paso 3: Lanzar un contenedor y probar la conexión

Ahora, lanzamos un contenedor temporal (por ejemplo, `alpine`) en la misma red para verificar que podemos "ver" a la base de datos por su nombre.

docker run -it --rm --network app-network alpine sh

Una vez dentro de la shell de Alpine, usamos el comando `ping` (primero hay que instalarlo):

# Dentro del contenedor de Alpine
apk add --no-cache iputils
ping mi-postgres-db

Verás que el `ping` se resuelve a la dirección IP interna del contenedor `mi-postgres-db` y recibe respuesta. ¡La resolución de nombres funciona!

Esto significa que si tuvieras un contenedor con una aplicación Node.js, Python o Java en la misma red, la cadena de conexión a la base de datos podría ser algo como:

postgresql://user:password@mi-postgres-db:5432/database_name

Fíjate que usamos el nombre del contenedor, `mi-postgres-db`, como el host de la base de datos. Docker se encarga de todo lo demás.