Conectando Nginx no Docker ao Localhost MySQL na máquina host

Conectando Nginx no Docker ao Localhost MySQL na máquina host
Shell

Acessando serviços Localhost de contêineres Docker

Executar o Nginx dentro de um contêiner Docker enquanto precisa se conectar a uma instância do MySQL na máquina host pode ser desafiador, especialmente quando o MySQL está vinculado apenas ao host local. Esta configuração evita que o contêiner acesse diretamente o serviço MySQL usando métodos de rede padrão.

Este artigo explora várias soluções para preencher essa lacuna, permitindo conectividade perfeita entre contêineres Docker e serviços em execução no host local do host. Discutiremos por que os métodos comuns podem ser insuficientes e forneceremos etapas práticas para alcançar a conectividade desejada.

Comando Descrição
docker network create --driver bridge hostnetwork Cria uma rede Docker personalizada com um driver bridge, permitindo que contêineres se comuniquem dentro da mesma rede.
host_ip=$(ip -4 addr show docker0 | grep -oP '(? Extrai o endereço IP da interface docker0 do host, que é usada para conectar do contêiner aos serviços do host.
docker exec -it nginx-container bash Executa um shell bash interativo dentro do contêiner Nginx em execução para acesso direto à linha de comando.
mysql -h $host_ip -u root -p Comando usado dentro do contêiner Nginx para conectar-se ao servidor MySQL em execução na máquina host usando o endereço IP extraído.
networks: hostnetwork: external: true Configuração no Docker Compose para usar uma rede Docker criada 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 Grava uma nova configuração Nginx para fazer proxy de solicitações MySQL para a máquina host.
nginx -s reload Recarrega o serviço Nginx para aplicar as novas alterações de configuração.

Configurando Docker e Nginx para acessar serviços de host

Para conectar um contêiner Nginx a uma instância MySQL em execução no host, primeiro precisamos estabelecer uma ponte de rede. O comando docker network create --driver bridge hostnetwork cria essa rede personalizada, permitindo a comunicação entre contêineres na mesma rede. Em seguida, iniciamos os contêineres MySQL e Nginx nesta rede usando docker run --name mysql-container --network hostnetwork -e MYSQL_ROOT_PASSWORD=root -d mysql:latest e docker run --name nginx-container --network hostnetwork -d nginx:latest, respectivamente. Essa configuração permite que os contêineres descubram e se comuniquem entre si. Para conectar-se ao MySQL a partir do Nginx, precisamos do endereço IP do host, que pode ser obtido com host_ip=$(ip -4 addr show docker0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}'). Este comando captura o endereço IP da interface docker0 no host.

A seguir, usamos docker exec -it nginx-container bash para abrir um shell interativo no contêiner Nginx. A partir daqui, podemos iniciar uma conexão MySQL usando mysql -h $host_ip -u root -p, onde $host_ip é o endereço IP do host. Alternativamente, usar o Docker Compose simplifica o processo definindo serviços e redes em um arquivo YAML. O networks: hostnetwork: external: true A configuração garante que os serviços usem uma rede criada externamente. Finalmente, para configurar o Nginx para fazer proxy de solicitações MySQL, atualizamos seu arquivo de configuração com echo "server { listen 80; location / { proxy_pass http://host.docker.internal:3306; } }" > /etc/nginx/conf.d/default.conf e recarregue o Nginx usando nginx -s reload. Esta configuração permite que o Nginx encaminhe solicitações para a instância MySQL em execução no host.

Conectando o Docker Container ao MySQL do Host via Network Bridge

Shell Script para configuração de rede 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

Usando Docker Compose para vincular Nginx e MySQL do Host

Configuração YAML do 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

Configurando o Nginx para conectar-se ao host MySQL usando a rede Docker

Configuração Nginx e comando de rede 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

Conectando contêineres Docker a serviços locais de host

Ao executar aplicativos em contêineres Docker, acessar serviços vinculados ao host local do host pode ser um desafio devido ao isolamento da rede. Uma abordagem eficaz é usar o modo de rede host do Docker. Ao iniciar um contêiner com o --network host opção, o contêiner compartilha a pilha de rede do host, permitindo que ele acesse diretamente os serviços vinculados ao localhost. No entanto, este modo é menos portátil e pode não funcionar bem em todos os ambientes, como Docker Swarm ou Kubernetes.

Outra abordagem é usar o resolvedor DNS integrado do Docker, host.docker.internal. Esse nome DNS especial é resolvido para o endereço IP do host, permitindo que os contêineres se comuniquem com os serviços no host. Este método é simples e evita as complexidades do gerenciamento de rede. No entanto, está disponível apenas no Docker para Windows e Mac, não no Linux. Para usuários do Linux, criar uma rede de ponte personalizada e configurar manualmente as regras de roteamento é uma solução viável. Isto envolve usar o ip e iptables comandos para rotear o tráfego da rede de contêineres para a interface localhost do host.

Perguntas comuns sobre como conectar contêineres Docker a serviços de host

  1. Como faço para usar o --network host opção no Docker?
  2. Execute seu contêiner com docker run --network host para compartilhar a pilha de rede do host.
  3. O que é host.docker.internal?
  4. É um nome DNS especial que resolve o endereço IP do host, disponível no Docker para Windows e Mac.
  5. Eu posso usar host.docker.internal no Linux?
  6. Não, este recurso não está disponível no Docker para Linux.
  7. Como posso criar uma rede de ponte personalizada?
  8. Usar docker network create --driver bridge my-bridge-network para criar uma rede de ponte personalizada.
  9. Qual é o propósito do iptables comando?
  10. Ele gerencia a filtragem de pacotes de rede e regras de roteamento em sistemas Linux.
  11. Como me conecto a uma instância MySQL no host a partir de um contêiner Docker?
  12. Usar mysql -h host.docker.internal -u root -p para Docker no Windows/Mac ou configure o roteamento para Linux.
  13. Quais são as limitações de uso --network host?
  14. Pode reduzir a portabilidade e não é compatível com alguns orquestradores como o Kubernetes.
  15. Posso acessar outros serviços no host além do MySQL?
  16. Sim, usando os mesmos métodos, você pode se conectar a qualquer serviço em execução no host.

Considerações finais sobre como acessar serviços de host do Docker

Conectar-se a uma instância MySQL no host a partir de um contêiner Nginx envolve vários métodos, cada um com seus próprios benefícios e limitações. O uso de redes de host, nomes DNS especiais ou pontes de rede personalizadas pode efetivamente preencher a lacuna, garantindo uma comunicação tranquila entre contêineres Docker e serviços de host. Ao compreender e implementar essas estratégias, você pode superar os desafios de isolamento de rede e manter conexões robustas em seu ambiente Dockerizado.