扩展您的 Compose 文件

Docker Compose 的 extends 属性 让您可以在不同的文件之间,甚至完全不同的项目之间共享通用配置。

如果您有多个服务需要复用一组通用的配置选项,那么扩展服务将非常有用。借助 extends,您可以在一处定义一组通用的服务选项,并从任何位置引用它。您可以引用另一个 Compose 文件,选择您希望在自己的应用中使用的服务,并根据自身需求覆盖部分属性。

重要

当您使用多个 Compose 文件时,必须确保文件中的所有路径都相对于基础 Compose 文件(即位于主项目文件夹中的 Compose 文件)。这是必需的,因为扩展文件不必是有效的 Compose 文件。扩展文件可以包含配置的小型片段。追踪服务的哪个片段相对于哪个路径既困难又令人困惑,因此为了使路径更易于理解,所有路径都必须相对于基础文件进行定义。

工作原理

从另一个文件扩展服务

请看以下示例:

services:
  web:
    extends:
      file: common-services.yml
      service: webapp

这将指示 Compose 仅重用在 common-services.yml 文件中定义的 webapp 服务的属性。webapp 服务本身不是最终项目的一部分。

如果 common-services.yml 看起来是这样:

services:
  webapp:
    build: .
    ports:
      - "8000:8000"
    volumes:
      - "/data"

您获得的结果与直接在 web 下定义相同的 buildportsvolumes 配置值并编写 docker-compose.yml 时完全一致。

当从另一个文件扩展服务时,若要将服务 webapp 包含在最终项目中,您需要在当前的 Compose 文件中显式地包含这两个服务。例如(请注意,这是一个非规范性示例):

services:
  web:
    build: alpine
    command: echo
    extends:
      file: common-services.yml
      service: webapp
  webapp:
    extends:
      file: common-services.yml
      service: webapp

或者,您可以使用 include

在同一文件中扩展服务

如果您在同一个 Compose 文件中定义服务,并从另一个服务扩展某个服务,则原始服务和被扩展的服务都将包含在您的最终配置中。例如:

services:
  web:
    build: alpine
    extends: webapp
  webapp:
    environment:
      - DEBUG=1

在同一文件中和从另一个文件扩展服务

您可以更进一步,在compose.yaml中本地定义或重新定义配置:

services:
  web:
    extends:
      file: common-services.yml
      service: webapp
    environment:
      - DEBUG=1
    cpu_shares: 5

  important_web:
    extends: web
    cpu_shares: 10

更多示例

扩展单个服务在您拥有多个具有共同配置的服务时非常有用。下面的示例是一个包含两个服务的 Compose 应用:一个 Web 应用程序和一个队列工作器。这两个服务使用相同的代码库,并共享许多配置选项。

common.yaml 文件定义了通用配置:

services:
  app:
    build: .
    environment:
      CONFIG_FILE_PATH: /code/config
      API_KEY: xxxyyy
    cpu_shares: 5

docker-compose.yaml 定义了使用通用配置的具体服务:

services:
  webapp:
    extends:
      file: common.yaml
      service: app
    command: /code/run_web_app
    ports:
      - 8080:8080
    depends_on:
      - queue
      - db

  queue_worker:
    extends:
      file: common.yaml
      service: app
    command: /code/run_worker
    depends_on:
      - queue

例外与限制

volumes_fromdepends_on 在使用 extends 的服务之间永远不会共享。存在这些例外是为了避免隐式依赖;您始终需要在本地定义 volumes_from。这确保了在读取当前文件时,服务之间的依赖关系清晰可见。在本地定义这些内容还能确保对被引用文件的更改不会导致任何问题。

extends 仅在您只需要共享单个服务,并且熟悉所扩展的文件以便调整配置时才有用。但是,当您想要复用他人不熟悉的配置,且不了解其自身依赖关系时,这不是一个可接受的解决方案。

相对路径

当对指向另一个文件夹的 file 属性使用 extends 时,被扩展服务声明的相对路径会被转换,以确保扩展服务使用时仍指向同一文件。以下示例对此进行了说明:

基础 Compose 文件:

services:
  webapp:
    image: example
    extends:
      file: ../commons/compose.yaml
      service: base

文件 commons/compose.yaml

services:
  base:
    env_file: ./container.env

生成的服务指向 commons 目录中的原始 container.env 文件。可以通过 docker compose config 来确认这一点,它会检查实际的模型:

services:
  webapp:
    image: example
    env_file: 
      - ../commons/container.env

参考信息