Compose 中的网络

Important

Docker 的文档引用并描述了 Compose V2 的功能。

自 2023 年 7 月起,Compose V1 停止更新,并且不再包含在新的 Docker Desktop 版本中。Compose V2 已取代 Compose V1,并集成到所有当前的 Docker Desktop 版本中。有关更多信息,请参阅 迁移到 Compose V2

默认情况下,Compose 为您的应用设置一个单一的 网络。每个服务的容器都会加入默认网络,既可以被该网络中的其他容器访问,也可以通过服务名称被发现。

Note

您的应用网络的名称基于“项目名称”,而项目名称又基于其所在目录的名称。您可以通过 --project-name 标志COMPOSE_PROJECT_NAME 环境变量 覆盖项目名称。

例如,假设您的应用位于名为 myapp 的目录中,并且您的 compose.yaml 如下所示:

services:
  web:
    build: .
    ports:
      - "8000:8000"
  db:
    image: postgres:18
    ports:
      - "8001:5432"

当您运行 docker compose up 时,会发生以下情况:

  1. 创建一个名为 myapp_default 的网络。
  2. 使用 web 的配置创建一个容器。它以名称 web 加入网络 myapp_default
  3. 使用 db 的配置创建一个容器。它以名称 db 加入网络 myapp_default

现在,每个容器都可以查找服务名称 webdb,并获得相应容器的 IP 地址。例如,web 的应用程序代码可以连接到 URL postgres://db:5432 并开始使用 Postgres 数据库。

需要注意的是 HOST_PORTCONTAINER_PORT 之间的区别。在上面的示例中,对于 dbHOST_PORT8001,容器端口是 5432(postgres 默认)。网络服务之间的通信使用 CONTAINER_PORT。当定义了 HOST_PORT 时,服务也可以在 swarm 外部访问。

web 容器中,您连接到 db 的连接字符串将类似于 postgres://db:5432,而从主机,连接字符串将类似于 postgres://{DOCKER_IP}:8001,例如,如果您的容器在本地运行,则为 postgres://localhost:8001

更新网络上的容器

如果您对服务进行了配置更改并运行 docker compose up 进行更新,旧的容器将被移除,新的容器将以不同的 IP 地址但相同的名称加入网络。正在运行的容器可以查找该名称并连接到新地址,但旧地址将停止工作。

如果任何容器与旧容器有开放的连接,这些连接将被关闭。容器有责任检测这种情况,再次查找名称并重新连接。

Tip

尽可能通过名称而不是 IP 引用容器。否则,您将需要不断更新使用的 IP 地址。

链接容器

链接允许您定义额外的别名,通过该别名可以从另一个服务访问服务。它们不是启用服务通信所必需的。默认情况下,任何服务都可以通过该服务的名称访问任何其他服务。在以下示例中,db 可以通过主机名 dbdatabaseweb 访问:

services:
  web:
    build: .
    links:
      - "db:database"
  db:
    image: postgres:18

有关更多信息,请参见 链接参考

多主机网络

当在启用了 Swarm 模式 的 Docker 引擎上部署 Compose 应用时,您可以使用内置的 overlay 驱动程序来实现多主机通信。

Overlay 网络始终创建为 attachable。您可以选择性地将 attachable 属性设置为 false

请查阅 Swarm 模式部分 以了解如何设置 Swarm 集群,并查阅 overlay 网络驱动程序文档 以了解有关多主机 overlay 网络的信息。

指定自定义网络

除了使用默认应用网络外,您还可以使用顶级 networks 键指定自己的网络。这使您可以创建更复杂的拓扑结构,并指定 自定义网络驱动程序 和选项。您还可以使用它来连接服务到 Compose 不管理的外部创建的网络。

每个服务都可以通过服务级别的 networks 键指定要连接的网络,这是一个引用顶级 networks 键下条目的名称列表。

以下示例显示了一个定义了两个自定义网络的 Compose 文件。proxy 服务与 db 服务隔离,因为它们没有共享网络。只有 app 可以同时与两者通信。

services:
  proxy:
    build: ./proxy
    networks:
      - frontend
  app:
    build: ./app
    networks:
      - frontend
      - backend
  db:
    image: postgres:18
    networks:
      - backend

networks:
  frontend:
    # 指定驱动程序选项
    driver: bridge
    driver_opts:
      com.docker.network.bridge.host_binding_ipv4: "127.0.0.1"
  backend:
    # 使用自定义驱动程序
    driver: custom-driver

可以通过为每个附加网络设置 ipv4_address 和/或 ipv6_address 来使用静态 IP 地址配置网络。

网络也可以指定 自定义名称

services:
  # ...
networks:
  frontend:
    name: custom_frontend
    driver: custom-driver-1

配置默认网络

除了指定自己的网络外,您还可以通过定义一个名为 defaultnetworks 条目来更改应用范围的默认网络设置:

services:
  web:
    build: .
    ports:
      - "8000:8000"
  db:
    image: postgres:18

networks:
  default:
    # 使用自定义驱动程序
    driver: custom-driver-1

使用现有网络

如果您使用 docker network create 命令在 Compose 外部手动创建了一个桥接网络,您可以通过将网络标记为 external 来将 Compose 服务连接到它。

如果您希望您的容器加入一个预先存在的网络,请使用 external 选项

services:
  # ...
networks:
  network1:
    name: my-pre-existing-network
    external: true

Compose 不会尝试创建一个名为 [projectname]_default 的网络,而是查找名为 my-pre-existing-network 的网络,并将您的应用容器连接到它。

进一步参考信息

有关可用网络配置选项的完整详细信息,请参见以下参考: