Расширение службы в docker-compose 3

Я создал службу для docker-compose 3, которая использует множество переменных среды:

version: "3"

services:
  myservice:
    build:
      context: ./myservice
    command: ./something
    environment:
      VAR1: "val1"
      VAR2: "val2"
      VAR3: "val3"

Теперь я хочу добавить службу, которая использует те же значения переменных среды, кроме VAL1, и имеет другую команду:

myotherservice:
    build:
      context: ./myservice
    command: ./somethingelse
    environment:
      VAR1: "val1-bis"
      VAR2: "val2"
      VAR3: "val3"

Есть ли способ избежать дублирования переменных среды в файле docker-compose.yml? В docker-compose 2 можно было использовать ключевое слово extends но это уже не так в docker-compose 3.

EDIT: в октябре 2017 года поля дополнений были добавлены в синтаксис docker-compose 3.4: https://docs.docker.com/compose/compose-file/#extension-fields. Это правильный путь:

version: "3"
x-env:
  &default-env
  VAR1: "val1"
  VAR2: "val2"
  VAR3: "val3"
services:
  myservice:
    build:
      context: ./myservice
    command: ./something
    environment: *default-env
myotherservice:
    build:
      context: ./myservice
    command: ./somethingelse
    environment:
      << : *default-env
      VAR1: "val1-bis"

Ответ 1

Вы можете извлечь общие переменные среды в файл env.

После этого вы можете использовать опцию конфигурации env_file в вашем файле композиции.

-> cat common.env
      VAR2=val2
      VAR3=val3

Вы по-прежнему можете передавать/перезаписывать переменные среды, отличные от указанных в common.env, с помощью параметра конфигурации environment.

myotherservice:
  build:
    context: ./myservice
  command: ./somethingelse
  env_file: ./common.env
  environment:
    VAR1: "val1-bis"

Ссылка

Ответ 2

Это очень легко с YAML:

version: "3"

services:
  myservice: &myservice
    build:
      context: ./myservice
    command: ./something
    environment: &myservice_environment
      VAR1: "val1"
      VAR2: "val2"
      VAR3: "val3"

myotherservice:
    <<: *myservice
    environment:
      <<: *myservice_environment
      VAR1: "val1-bis"

Смотрите документ о полях расширения.

Ответ 3

Будьте внимательны при использовании типа слияния YAML в соответствии с рекомендациями OP и полей расширения документации.

Тип слияния работает только с словарями/картами, но не с массивами/списками. К счастью, раздел окружения может быть словарем или массивом. Так что пример OP с разделом среды работает.

Однако раздел томов должен быть массивом, поэтому объединение не будет работать там. Необходимость в массиве не упоминается в документации, но быстрый локальный тест показывает ...volumes contains an invalid type, it should be an array с версией докера 18.09.2

В заключение, якоря, псевдонимы и типы слияния могут помочь вам во многих случаях, но они работают иначе, чем слияние нескольких файлов компоновки с помощью docker-compose -f file1 file2, и отличаются от директивы extends в compose 2. Там объединение списков работает как положено.