从实列中学习linux shell14: docker-compose.yaml 中 多个服务 相对于 其中的 network 服务之前怎么访问,以及 和 从host 主机如何访问

在 Docker Compose 中,服务之间的网络访问和与宿主机的交互是通过网络配置端口映射实现的。以下是详细解释和实际示例:


一、服务间的相互访问

1. 默认网络行为

当使用 docker-compose up 启动服务时,Docker Compose 会自动创建一个默认网络(通常以项目名称为前缀),所有服务默认加入该网络,并通过服务名称(service name) 作为主机名互相访问。

示例配置
version: "3.8"

services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    depends_on:
      - api

  api:
    image: my-api:latest
    expose:
      - "3000"  # 仅在容器间暴露端口,不映射到宿主机
访问方式
  • web 服务可以直接通过 http://api:3000 访问 api 服务(使用服务名称 api 作为主机名)
  • 无需手动配置网络,Docker Compose 已自动处理

2. 自定义网络

如果需要更精细的控制(例如隔离部分服务),可以显式定义网络:

示例配置
version: "3.8"

services:
  web:
    image: nginx:alpine
    networks:
      - frontend
    ports:
      - "80:80"

  api:
    image: my-api:latest
    networks:
      - frontend
      - backend
    expose:
      - "3000"

  database:
    image: postgres:15
    networks:
      - backend
    environment:
      POSTGRES_PASSWORD: secret

networks:
  frontend:
  backend:
访问规则
  • webapifrontend 网络中,可以互相访问
  • apidatabasebackend 网络中,可以互相访问
  • web 无法直接访问 database(不在同一网络)

二、从宿主机访问服务

1. 通过端口映射(ports)

使用 ports 将容器端口映射到宿主机端口:

services:
  web:
    image: nginx:alpine
    ports:
      - "8080:80"  # 宿主机的 8080 端口映射到容器的 80 端口
  • 宿主机访问http://localhost:8080http://<宿主IP>:8080
  • 其他容器访问:通过服务名 web:80(无需端口映射)

2. 仅容器间访问(expose)
services:
  api:
    image: my-api:latest
    expose:
      - "3000"  # 仅暴露给其他容器,宿主机无法直接访问
  • 宿主机无法访问 api:3000
  • 其他容器可通过 http://api:3000 访问

三、关键概念对比

配置项作用范围示例典型用途
ports宿主机 ↔ 容器- "80:80"允许外部访问服务
expose容器 ↔ 容器- "3000"内部服务间通信
networks容器间网络隔离自定义网络名称控制服务间通信权限

四、完整示例

version: "3.8"

services:
  frontend:
    image: nginx:alpine
    ports:
      - "80:80"
    networks:
      - public

  backend:
    image: node:18
    expose:
      - "3000"
    networks:
      - public
      - private
    environment:
      DB_HOST: database

  database:
    image: postgres:15
    networks:
      - private
    volumes:
      - pg_data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: secret

networks:
  public:
  private:

volumes:
  pg_data:
访问逻辑
  1. 宿主机访问

    • frontend 通过 http://localhost:80 访问
    • backenddatabase 无法直接从宿主机访问(未配置 ports
  2. 服务间访问

    • frontend 可通过 http://backend:3000 访问 backend
    • backend 可通过 postgres://database:5432 访问 database
    • frontend 无法 直接访问 database(不在同一网络)

五、调试技巧

1. 查看容器IP
docker-compose exec <service_name> ip a
2. 测试容器间连通性
docker-compose exec frontend ping backend
3. 查看网络详情
docker network inspect <network_name>

六、常见问题

Q1:为什么服务间无法通过服务名访问?
  • 确保服务在同一个网络
  • 检查服务名称拼写(区分大小写)
  • 确认目标服务已正确 exposeports 端口
Q2:如何从宿主机访问未映射端口的服务?
  • 临时进入容器网络:
    docker run --rm -it --network <project_name>_public nicolaka/netshoot curl http://backend:3000
    
Q3:如何让宿主机解析服务名称?
  • 在 Docker Desktop 中可使用 host.docker.internal 作为宿主机别名
  • Linux 环境下需手动配置路由或 DNS
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一刀到底211

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值