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 或其他服务,这时使用 host.docker.internal 是一种方便的解决方案。
通过这种方式,你的 task 容器能够成功连接到本地的 MySQL 服务,从而解决了之前的连接问题。
本文已收录在Github,关注我,紧跟本系列专栏文章,咱们下篇再续!
作者简介:魔都架构师,多家大厂后端一线研发经验,在分布式系统设计、数据平台架构和AI应用开发等领域都有丰富实践经验。
各大技术社区头部专家博主。具有丰富的引领团队经验,深厚业务架构和解决方案的积累。
负责:
- 中央/分销预订系统性能优化
- 活动&券等营销中台建设
- 交易平台及数据中台等架构和开发设计
- 车联网核心平台-物联网连接平台、大数据平台架构设计及优化
- LLM Agent应用开发
- 区块链应用开发
- 大数据开发挖掘经验
- 推荐系统项目
目前主攻市级软件项目设计、构建服务全社会的应用系统。
参考:
- 编程严选网