原来如此!Docker容器连不上本地MySQL只因为漏了这一步!

64 阅读2分钟

本文已收录在Github关注我,紧跟本系列专栏文章,咱们下篇再续!

  • 🚀 魔都架构师 | 全网30W技术追随者
  • 🔧 大厂分布式系统/数据中台实战专家
  • 🏆 主导交易系统百万级流量调优 & 车联网平台架构
  • 🧠 AIGC应用开发先行者 | 区块链落地实践者
  • 🌍 以技术驱动创新,我们的征途是改变世界!
  • 👉 实战干货:编程严选网

0 问题背景

PC本地已安装了 MySQL 服务,默认暴露 3306 端口。现有一个 docker-compose 部署的服务,想通过 docker-desktop 在 PC 本地完成部署,观察效果。docker-compose 配置文件已经移除 MySQL 相关配置,而是直接使用 PC 即容器宿主机上的 MySQL 服务:

version: '3.8'
services:
  task-app:
    image: task
    environment:
      - SPRING_DATASOURCE_URL=jdbc:mysql://localhost:3306/task
      - SPRING_LIQUIBASE_URL=jdbc:mysql://localhost:3306/task

但是 task 服务容器一直无法连接 MySQL,把localhost改成host.docker.internal就能连接到本地MySQL服务,task容器启动正常。说明Docker中的容器与主机之间的网络通信有特殊处理。

1 localhost含义

在 Docker 容器中用 localhost 时,它指容器自身的网络环境,而非宿主机(你的 PC)。

因此,若你的 MySQL 服务在宿主机运行,容器内的应用程序无法通过 localhost 访问,因为容器不知道宿主机网络。

2 host.docker.internal作用

host.docker.internal 是 Docker 提供的一个特殊 DNS 名称,它允许容器访问宿主机的网络。

在容器中用 host.docker.internal ,Docker 会将该地址解析为宿主机的 IP 地址,使容器能与宿主机上的服务(如 MySQL)通信。

3 原理

网络隔离:Docker 容器运行在一个隔离的网络环境中,默认情况下,容器无法直接访问宿主机的服务。

特殊 DNS 名称:host.docker.internal 提供了一种方式,让容器能够访问宿主机的服务,解决了容器与宿主机之间的网络隔离问题。

4 使用场景

当你在开发环境中使用 Docker 时,常常需要容器访问宿主机上的数据库、API 或其他服务时。