Docker · 网络

端口映射 与 容器互调

搞懂"冒号左右"到底看哪个 · 一篇讲透两种网络场景

1

先记住这条映射规则

— 它是后面一切的基础

Docker Compose 里的端口映射格式永远是:

宿主机端口 : 容器端口
   左边        右边

一个口诀:左边是"门牌号",右边是"房间号"。外部世界按门牌号找你,房间内部互相串门用的是房间号。

        外部访问(浏览器、IDEA、其他机器)
                  │
                  ▼
   ┌──────────────────────────┐
   │   宿主机 Windows           │
   │   localhost:3306  ◀── 左边端口(门牌号)
   │         │ 映射              │
   │   ┌─────┴──────────────┐   │
   │   │  容器 mysql          │   │
   │   │  内部监听 3306     │  ◀── 右边端口(房间号)
   │   └────────────────────┘   │
   └──────────────────────────┘
💡 关键区分
左边由你决定,可以随便改(避开冲突即可);右边是镜像固定的服务端口,不要乱改——改了容器里的服务并不会跟着换监听端口,映射就失效了。
2

你的应用连哪个端口?

— 这才是你最常遇到的场景

看冒号左边(宿主机端口)。因为你的应用在 IDEA 里跑、在 Windows 宿主机上跑,它只能触达暴露在宿主机上的那个端口。

你要连的服务用什么端口连接串示例
MySQL3306jdbc:mysql://localhost:3306/app_db
Redis6379redis://localhost:6379
MongoDB27017mongodb://root:root123@localhost:27017
RabbitMQ(AMQP)5672amqp://localhost:5672
RabbitMQ(管理界面)15672http://localhost:15672
RocketMQ NameServer9876namesrv=localhost:9876
RocketMQ Dashboard8180http://localhost:8180
3

两种网络场景,分清楚就懂了

— "容器互调"到底什么时候出现
💻场景 A:应用在宿主机跑
你在 IDEA 点绿色按钮跑 Spring Boot —— 进程在 Windows 上,不在任何容器里。
  • 连 mysql 必须走宿主机映射
  • host 写 localhost
  • 端口用冒号左边
// ✅ 你日常用的方式
jdbc:mysql://localhost:3306/app_db
📦场景 B:应用也容器化了
你的 Spring Boot 也打成镜像、用 docker 跑起来 —— 这时"容器互调"才出现。
  • 走容器内部高速公路,不经宿主映射
  • host 写服务名
  • 端口用冒号右边(容器内端口)
// 容器之间互相调用
jdbc:mysql://mysql:3306/app_db

为什么场景 B 不能用 localhost?因为容器里的 localhost 指的是容器自己,不是宿主机。它在自己的小房间里喊"localhost",没人应答。

4

最直观的对比:同一个 mysql 容器

— 改映射端口后会发生什么

假设把 compose 改成 9999:3306,同一个是 mysql 容器,两种访问方式的表现完全不同:

访问方原来改映射后受影响吗
本地 IDEA(宿主机)localhost:3306localhost:9999必须改
另一个容器(app)mysql:3306mysql:3306完全不变
✅ 原理一句话
宿主机映射是"对外开的一扇门",改门牌号只影响外面找门的人;容器之间走的是内部走廊,跟那扇门无关,所以右边端口永远不变。
5

为什么你可能从没见过容器互调?

— 很正常,不是你漏学了

因为目前你的工作流是 "中间件用 Docker,应用本地 IDEA 跑"——这是开发期最舒服的方式。你的应用根本不在容器里,所以永远只用 localhost:左边端口 这一招,自然碰不到容器互调。

容器互调通常出现在这些场合:

  1. 完整 docker-compose 起整套 —— app + db 全部容器化,常见于演示、联调、给同事一键拉起
  2. CI/CD 流水线 —— 跑集成测试时,测试服务容器要连数据库容器
  3. Kubernetes 部署 —— Pod 之间互相调用,原理一脉相承(Service 名解析)
  4. 微服务全家桶容器化 —— 订单服务容器调用户服务容器、调网关容器
⚠️ 容器互调的完整写法长这样
哪天你把应用也丢进 compose,配置就变成下面这样。注意 environment 里的连接串:
services:
  mysql:
    image: mysql:8.0
    ...

  app:                          # ← 你的应用也成了容器
    image: my-app:latest
    depends_on: [mysql]
    environment:
      # host 是服务名 mysql,端口是容器内 3306(右边)
      - SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/app_db
      #  ↑↑↑ 注意:不是 localhost,不是宿主机端口

🎯 给你的场景,记这三条就够

① 映射格式永远是 宿主机端口 : 容器端口,左边对外、右边对内。
② 你的应用在 IDEA 里跑 → 永远用 localhost:左边端口 连这些中间件。
③ 容器之间互调 → 用 服务名:右边端口,跟你改不改左边映射无关。这条现在用不上,等应用也容器化再说。