将 Docker 中的 Nginx 连接到主机上的本地 MySQL

将 Docker 中的 Nginx 连接到主机上的本地 MySQL
Shell

从 Docker 容器访问本地主机服务

在 Docker 容器内运行 Nginx,同时需要连接到主机上的 MySQL 实例可能具有挑战性,特别是当 MySQL 仅绑定到 localhost 时。此设置可防止容器使用标准网络方法直接访问 MySQL 服务。

本文探讨了各种解决方案来弥补这一差距,从而实现 Docker 容器与主机本地主机上运行的服务之间的无缝连接。我们将讨论为什么常见方法可能达不到要求,并提供实现所需连接的实用步骤。

命令 描述
docker network create --driver bridge hostnetwork 使用桥接驱动程序创建自定义 Docker 网络,允许容器在同一网络内进行通信。
host_ip=$(ip -4 addr show docker0 | grep -oP '(? 提取主机 docker0 接口的 IP 地址,用于从容器连接到主机服务。
docker exec -it nginx-container bash 在正在运行的 Nginx 容器内执行交互式 bash shell,以进行直接命令行访问。
mysql -h $host_ip -u root -p Nginx 容器内使用的命令,使用提取的 IP 地址连接到主机上运行的 MySQL 服务器。
networks: hostnetwork: external: true Docker Compose 中的配置以使用外部创建的 Docker 网络。
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 写入新的 Nginx 配置以将 MySQL 请求代理到主机。
nginx -s reload 重新加载 Nginx 服务以应用新的配置更改。

配置Docker和Nginx访问主机服务

要将 Nginx 容器连接到主机上运行的 MySQL 实例,我们首先需要建立一个网桥。命令 docker network create --driver bridge hostnetwork 创建此自定义网络,从而实现同一网络上的容器之间的通信。然后我们使用以下命令在该网络上启动 MySQL 和 Nginx 容器 docker run --name mysql-container --network hostnetwork -e MYSQL_ROOT_PASSWORD=root -d mysql:latestdocker run --name nginx-container --network hostnetwork -d nginx:latest, 分别。此设置允许容器发现彼此并进行通信。要从 Nginx 连接到 MySQL,我们需要主机的 IP 地址,可以通过以下方式获取 host_ip=$(ip -4 addr show docker0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')。此命令捕获主机上 docker0 接口的 IP 地址。

接下来,我们使用 docker exec -it nginx-container bash 在 Nginx 容器中打开交互式 shell。从这里,我们可以使用以下命令启动 MySQL 连接 mysql -h $host_ip -u root -p, 在哪里 $host_ip 是主机的IP地址。或者,使用 Docker Compose 通过在 YAML 文件中定义服务和网络来简化流程。这 networks: hostnetwork: external: true 配置确保服务使用外部创建的网络。最后,为了配置 Nginx 来代理 MySQL 请求,我们将其配置文件更新为 echo "server { listen 80; location / { proxy_pass http://host.docker.internal:3306; } }" > /etc/nginx/conf.d/default.conf 并使用重新加载 Nginx nginx -s reload。此设置允许 Nginx 将请求转发到主机上运行的 MySQL 实例。

通过网桥将Docker容器连接到主机的MySQL

用于 Docker 网络设置的 Shell 脚本

# 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

使用Docker Compose链接Nginx和主机的MySQL

Docker Compose YAML 配置

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

配置 Nginx 使用 Docker 网络连接到主机 MySQL

Nginx 配置和 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

连接 Docker 容器以托管本地服务

在 Docker 容器中运行应用程序时,由于网络隔离,访问绑定到主机本地主机的服务可能会很困难。一种有效的方法是使用Docker的主机网络模式。通过启动一个容器 --network host 选项,容器共享主机的网络堆栈,允许它直接访问本地主机绑定的服务。然而,这种模式的可移植性较差,可能无法在所有环境中正常工作,例如 Docker Swarm 或 Kubernetes。

另一种方法是使用 Docker 内置的 DNS 解析器, host.docker.internal。这个特殊的 DNS 名称解析为主机的 IP 地址,使容器能够与主机上的服务进行通信。这种方法简单直接,避免了网络管理的复杂性。但是,它仅适用于 Windows 和 Mac 的 Docker,不适用于 Linux。对于Linux用户来说,创建自定义桥接网络并手动配置路由规则是一个可行的解决方案。这涉及使用 ipiptables 将流量从容器网络路由到主机的本地主机接口的命令。

有关将 Docker 容器连接到主机服务的常见问题

  1. 我该如何使用 --network host Docker 中的选项?
  2. 运行你的容器 docker run --network host 共享主机的网络堆栈。
  3. 什么是 host.docker.internal
  4. 它是一个特殊的 DNS 名称,可解析为主机的 IP 地址,可在适用于 Windows 和 Mac 的 Docker 上使用。
  5. 我可以用吗 host.docker.internal 在 Linux 上?
  6. 不可以,此功能在 Linux 版 Docker 上不可用。
  7. 如何创建自定义桥接网络?
  8. 使用 docker network create --driver bridge my-bridge-network 创建自定义桥接网络。
  9. 目的是什么 iptables 命令?
  10. 它管理 Linux 系统上的网络数据包过滤和路由规则。
  11. 如何从 Docker 容器连接到主机上的 MySQL 实例?
  12. 使用 mysql -h host.docker.internal -u root -p 对于 Windows/Mac 上的 Docker 或为 Linux 配置路由。
  13. 使用有什么限制 --network host
  14. 它可能会降低可移植性,并且与 Kubernetes 等某些编排器不兼容。
  15. 除了MySQL之外,我还可以访问主机上的其他服务吗?
  16. 是的,使用相同的方法,您可以连接到主机上运行的任何服务。

关于从 Docker 访问主机服务的最终想法

从 Nginx 容器连接到主机上的 MySQL 实例涉及多种方法,每种方法都有自己的优点和局限性。使用主机网络、特殊的 DNS 名称或自定义网桥可以有效地弥合差距,确保 Docker 容器和主机服务之间的顺畅通信。通过了解和实施这些策略,您可以克服网络隔离挑战并在 Docker 化环境中保持稳定的连接。