当Windows本地Redis与Docker的Redis容器共享6379端口一场诡异的和平共处一、问题背景最近在本地开发时遇到一个挺“反直觉”的问题Windows 11 本机已经启动了一个 Redis默认端口6379使用 Docker Desktop 再起一个 Redis 容器同样映射端口ports:-6379:6379docker-compose up 正常没有任何端口冲突报错按常识来说这应该直接报错port is already allocated。但现实是——两个 Redis 居然“共存”了。更奇怪的是用redis-cli连127.0.0.1:6379→ 命中的是本机 Redis用 RESP.app 连6379→ 也是本机 Redis只有把 Docker 改成6380:6379才能访问容器里的 Redis这说明Docker 映射成功了但流量没有打到容器里。二、现象复盘1️⃣ docker-compose 配置redis:image:redis:7-alpinecontainer_name:docker-redisrestart:alwaysports:-6379:63792️⃣ 端口占用情况netstat-ano|findstr :6379输出TCP 0.0.0.0:6379 LISTENING 5168 TCP 127.0.0.1:6379 LISTENING 6388 TCP [::]:6379 LISTENING 5168 TCP [::1]:6379 LISTENING 264123️⃣ 进程归属tasklist|findstr6388redis-server.exe6388tasklist|findstr5168com.docker.backend.exe5168 结论端口绑定进程127.0.0.1:6379本机 Redis0.0.0.0:6379Docker backend三、核心问题为什么两个进程都能“监听”6379端口而且不冲突四、底层原理分析1️⃣ 关键点绑定地址不同绑定方式含义127.0.0.1:6379仅本机回环0.0.0.0:6379所有网卡理论上0.0.0.0 应该包含 127.0.0.1但在 Windows Docker Desktop 场景下不是简单覆盖关系2️⃣ Docker Desktop 的特殊实现重点在 Windows 上Docker 并不是直接用 Linux 网络栈而是通过Hyper-V / WSL2 虚拟网络使用用户态代理userland proxy由com.docker.backend.exe接管端口 关键行为Docker 并不是直接 bind 真实的 6379而是做了一层“转发代理”3️⃣ 请求流向重点理解当你执行redis-cli-h127.0.0.1-p6379请求路径是客户端 → 127.0.0.1 → 命中本机 Redis不会经过 Docker如果访问本机IP:6379可能才会走客户端 → 0.0.0.0 → Docker backend → 容器 Redis4️⃣ 为什么不会冲突因为组件行为本机 Redis只监听 127.0.0.1Docker监听 0.0.0.0通过代理Windows TCP/IP 栈允许这种“分裂绑定”。五、验证方法✅ 方法1查看绑定地址netstat-ano|findstr :6379重点看127.0.0.1→ 本机服务0.0.0.0→ Docker✅ 方法2测试不同入口redis-cli-h127.0.0.1-p6379INFO server|findstr redis_version 我本机redis版本redis-cli-h192.168.0.1-p6379INFO server|findstr redis_version报错NOAUTH Authentication required.-a参数加上密码redis-cli-h192.168.0.1-p6379-atest123456 INFO server|findstr redis_version 我docker-compose.yml配置的redis版本六、为什么 RESP.app 也连不到 Docker因为默认连接127.0.0.1:6379 永远优先命中本机 Redis七、解决方案✅ 方案1推荐改端口映射ports:-6380:6379优点简单直接无歧义✅ 方案2关闭本机 Redisnet stop redis✅ 方案3让本机 Redis 绑定 0.0.0.0修改 redis.confbind 0.0.0.0⚠️ 风险端口冲突概率 ↑安全性 ↓✅ 方案4用容器网络访问推荐开发环境dockerexec-itdocker-redis redis-cli或者redis-cli-hhost.docker.internal-p6379八、经验总结踩坑复盘这次问题本质是“端口看起来一样但流量入口不同”几个关键认知Windows Docker Desktop ≠ Linux Docker0.0.0.0 ≠ 覆盖 127.0.0.1在该场景下Docker 端口映射是“代理”不是直接占用本机服务优先级更高loopback 优先九、最佳实践建议在日常开发中✅ 本机服务用默认端口6379✅ Docker 服务统一 16380、6381…✅ 或者统一走 Docker推荐微服务环境结语这个问题表面是“端口冲突”本质是网络栈 虚拟化 代理机制的组合行为如果不了解 Docker Desktop 的实现很容易被误导。希望这篇能帮你少踩一个坑 下次看到“端口没冲突但访问错服务”第一时间就该想到——流量路径问题。