Conexión de Nginx en Docker a Localhost MySQL en la máquina host

Conexión de Nginx en Docker a Localhost MySQL en la máquina host
Shell

Acceder a los servicios de Localhost desde contenedores Docker

Ejecutar Nginx dentro de un contenedor Docker mientras se necesita conectarse a una instancia de MySQL en la máquina host puede ser un desafío, especialmente cuando MySQL está vinculado solo a localhost. Esta configuración evita que el contenedor acceda directamente al servicio MySQL utilizando métodos de red estándar.

Este artículo explora varias soluciones para cerrar esta brecha, permitiendo una conectividad perfecta entre los contenedores Docker y los servicios que se ejecutan en el host local del host. Analizaremos por qué los métodos comunes pueden resultar insuficientes y proporcionaremos pasos prácticos para lograr la conectividad deseada.

Dominio Descripción
docker network create --driver bridge hostnetwork Crea una red Docker personalizada con un controlador puente, lo que permite que los contenedores se comuniquen dentro de la misma red.
host_ip=$(ip -4 addr show docker0 | grep -oP '(? Extrae la dirección IP de la interfaz docker0 del host, que se utiliza para conectarse desde el contenedor a los servicios del host.
docker exec -it nginx-container bash Ejecuta un shell bash interactivo dentro del contenedor Nginx en ejecución para acceso directo a la línea de comandos.
mysql -h $host_ip -u root -p Comando utilizado dentro del contenedor Nginx para conectarse al servidor MySQL que se ejecuta en la máquina host utilizando la dirección IP extraída.
networks: hostnetwork: external: true Configuración en Docker Compose para utilizar una red Docker creada externamente.
echo "server { listen 80; location / { proxy_pass http://host.docker.internal:3306; } }" >echo "server { listen 80; location / { proxy_pass http://host.docker.internal:3306; } }" > /etc/nginx/conf.d/default.conf Escribe una nueva configuración de Nginx para enviar solicitudes de MySQL a la máquina host.
nginx -s reload Vuelve a cargar el servicio Nginx para aplicar los nuevos cambios de configuración.

Configuración de Docker y Nginx para acceder a los servicios del host

Para conectar un contenedor Nginx a una instancia de MySQL que se ejecuta en el host, primero debemos establecer un puente de red. El comando docker network create --driver bridge hostnetwork crea esta red personalizada, permitiendo la comunicación entre contenedores en la misma red. Luego iniciamos los contenedores MySQL y Nginx en esta red usando docker run --name mysql-container --network hostnetwork -e MYSQL_ROOT_PASSWORD=root -d mysql:latest y docker run --name nginx-container --network hostnetwork -d nginx:latest, respectivamente. Esta configuración permite que los contenedores se descubran y se comuniquen entre sí. Para conectarnos a MySQL desde Nginx, necesitamos la dirección IP del host, que se puede obtener con host_ip=$(ip -4 addr show docker0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'). Este comando captura la dirección IP de la interfaz docker0 en el host.

A continuación, utilizamos docker exec -it nginx-container bash para abrir un shell interactivo en el contenedor Nginx. Desde aquí, podemos iniciar una conexión MySQL usando mysql -h $host_ip -u root -p, dónde $host_ip es la dirección IP del host. Alternativamente, usar Docker Compose simplifica el proceso al definir servicios y redes en un archivo YAML. El networks: hostnetwork: external: true La configuración garantiza que los servicios utilicen una red creada externamente. Finalmente, para configurar Nginx para enviar solicitudes MySQL, actualizamos su archivo de configuración con echo "server { listen 80; location / { proxy_pass http://host.docker.internal:3306; } }" > /etc/nginx/conf.d/default.conf y recargar Nginx usando nginx -s reload. Esta configuración permite a Nginx reenviar solicitudes a la instancia de MySQL que se ejecuta en el host.

Conexión del contenedor Docker al MySQL del host a través del puente de red

Script de Shell para la configuración de red Docker

# Create a Docker network
docker network create --driver bridge hostnetwork

# Run MySQL container with the created network
docker run --name mysql-container --network hostnetwork -e MYSQL_ROOT_PASSWORD=root -d mysql:latest

# Run Nginx container with the created network
docker run --name nginx-container --network hostnetwork -d nginx:latest

# Get the host machine's IP address
host_ip=$(ip -4 addr show docker0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')

# Connect to MySQL from within the Nginx container
docker exec -it nginx-container bash
mysql -h $host_ip -u root -p

Uso de Docker Compose para vincular Nginx y MySQL del host

Configuración YAML de Docker Compose

version: '3.8'

services:
  nginx:
    image: nginx:latest
    container_name: nginx-container
    networks:
      - hostnetwork

  mysql:
    image: mysql:latest
    container_name: mysql-container
    environment:
      MYSQL_ROOT_PASSWORD: root
    networks:
      - hostnetwork

networks:
  hostnetwork:
    external: true

Configuración de Nginx para conectarse al host MySQL mediante Docker Network

Configuración de Nginx y comando de red Docker

# Create a bridge network
docker network create bridge-network

# Run Nginx container with bridge network
docker run --name nginx-container --network bridge-network -d nginx:latest

# Run MySQL container on the host network
docker run --name mysql-container --network host -e MYSQL_ROOT_PASSWORD=root -d mysql:latest

# Update Nginx configuration to point to MySQL host
docker exec -it nginx-container bash
echo "server { listen 80; location / { proxy_pass http://host.docker.internal:3306; } }" > /etc/nginx/conf.d/default.conf
nginx -s reload

Conexión de contenedores Docker para alojar servicios locales

Cuando se ejecutan aplicaciones en contenedores Docker, acceder a los servicios vinculados al host local del host puede resultar complicado debido al aislamiento de la red. Un enfoque eficaz es utilizar el modo de red de host de Docker. Al iniciar un contenedor con el --network host Opción, el contenedor comparte la pila de red del host, lo que le permite acceder directamente a los servicios vinculados al host local. Sin embargo, este modo es menos portátil y es posible que no funcione bien en todos los entornos, como Docker Swarm o Kubernetes.

Otro enfoque es utilizar el solucionador de DNS integrado de Docker, host.docker.internal. Este nombre DNS especial se resuelve en la dirección IP del host, lo que permite que los contenedores se comuniquen con los servicios del host. Este método es sencillo y evita las complejidades de la gestión de la red. Sin embargo, sólo está disponible en Docker para Windows y Mac, no en Linux. Para los usuarios de Linux, crear una red puente personalizada y configurar manualmente las reglas de enrutamiento es una solución viable. Esto implica utilizar el ip y iptables comandos para enrutar el tráfico desde la red del contenedor a la interfaz localhost del host.

Preguntas comunes sobre la conexión de contenedores Docker a servicios de host

  1. ¿Cómo uso el --network host opción en Docker?
  2. Ejecute su contenedor con docker run --network host para compartir la pila de red del host.
  3. Qué es host.docker.internal?
  4. Es un nombre DNS especial que se resuelve en la dirección IP del host, disponible en Docker para Windows y Mac.
  5. Puedo usar host.docker.internal en linux?
  6. No, esta función no está disponible en Docker para Linux.
  7. ¿Cómo puedo crear una red puente personalizada?
  8. Usar docker network create --driver bridge my-bridge-network para crear una red puente personalizada.
  9. ¿Cuál es el propósito de la iptables ¿dominio?
  10. Gestiona el filtrado de paquetes de red y las reglas de enrutamiento en sistemas Linux.
  11. ¿Cómo me conecto a una instancia de MySQL en el host desde un contenedor Docker?
  12. Usar mysql -h host.docker.internal -u root -p para Docker en Windows/Mac o configurar el enrutamiento para Linux.
  13. ¿Cuáles son las limitaciones de uso? --network host?
  14. Puede reducir la portabilidad y no es compatible con algunos orquestadores como Kubernetes.
  15. ¿Puedo acceder a otros servicios en el host además de MySQL?
  16. Sí, utilizando los mismos métodos, puede conectarse a cualquier servicio que se ejecute en el host.

Reflexiones finales sobre el acceso a los servicios de host desde Docker

Conectarse a una instancia de MySQL en el host desde un contenedor Nginx implica varios métodos, cada uno con sus propios beneficios y limitaciones. El uso de redes de host, nombres DNS especiales o puentes de red personalizados puede cerrar la brecha de manera efectiva, garantizando una comunicación fluida entre los contenedores Docker y los servicios de host. Al comprender e implementar estas estrategias, puede superar los desafíos del aislamiento de la red y mantener conexiones sólidas en su entorno Dockerizado.