本文已收录在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 或其他服务时。