Moby: Добавить поддержку функции `extends` в Compose v3 / docker stack deploy

Созданный на 16 февр. 2017  ·  165Комментарии  ·  Источник: moby/moby

Как видно из https://github.com/docker/compose/issues/4315 , функция extends которая существует в docker-compose кажется популярной среди пользователей, несмотря на ее недостатки. Однако до сих пор он не был добавлен в реализацию формата Compose в движке. До сих пор мы советовали пользователям просто сгладить файловую структуру Compose при использовании v3, но является ли это долгосрочным решением, которое мы хотим использовать? Как мы можем предоставить четкий способ обновления для пользователей, которые полагаются на эту функцию?

cc @dnephin @vdemeester

arestack kinfeature

Самый полезный комментарий

Не только это, но и в журнале изменений написано, что «это было удалено, подробности см. В разделе« Как обновить »». Я смотрю на «как обновить», вы знаете, подробности о том, как обновить, и что там написано, это «см.« Расширение услуг »для подробностей». Я перехожу к «расширению служб», полагая, что наконец-то увижу способ расширить свои файлы, только чтобы увидеть «это было удалено, подробности см. В журнале изменений».

На данный момент это похоже на злую шутку, которую разыгрывает автор документации.

Все 165 Комментарий

Я добавил несколько примечаний https://github.com/docker/compose/issues/4315#issuecomment -280617251 мне, возвращая расширения, поскольку он существует до версии docker compose file 2.1, это не очень хорошая идея, но основная функция, которую я miss - иметь возможность объявлять абстрактные службы (которые никогда не должны запускаться, но могут использоваться для группировки общих свойств служб для удобства).

Согласился с комментариями docker / compose # 4315 о том, что способ работы extends был немного спартанским.

Я не буду рекомендовать решение, но FWIW, чтобы показать степень злоупотреблений, вот соглашения, которые украшают верхнюю часть нашего файла создания:

#
# Docker Compose configuration
#
# Due to lack of "expressivity" in Compose, we define our own couple of service
# "pseudo-types":
#
#   - image-only services (name: *-image)
#
#     The only goal of these is to build images. No other services build images.
#
#     These have entrypoint overridden to exit immediately.
#
#   - base services (name: *-base)
#
#     These contain common configuration and are intended to be extended.
#
#     Their command (not entrypoint, to keep the original one) is overridden to
#     exit immediately. Service must support a command to exit immediately.
#
#   - task services (name: *-task)
#
#     These are intended for running one-off commands.
#
#     Their default command is overridden to exit immediately. Service must
#     support a command to exit immediately.
#
#   - "real" services
#
#     These are actual services that stay up and running.
#
version: '2'
services:
  ...

Я думаю, что расширение v2.1 - хороший выбор. Extends на самом деле прост и понятен, это слишком хорошая практика для каждого окружения, чтобы иметь небольшое и удобочитаемое преобразование между dev, prod и env.

На самом деле у меня есть

  • общий файл docker-compose, который представляет базовые правила
  • докер для разработчиков, расширяющий его и с возможностями для разработчика
  • промежуточный докер также составляет общее расширение и со средствами для этой среды
  • производственный докер также составляет общее расширение и со средствами для этой среды, особенно репликацией контейнера, правилами перезапуска и т. д.

Это работает, и я не понимаю, почему мы должны искать в этом билете полностью переписанный вариант, а скорее сохранить интересную функцию. Расширения - хорошая часть со специальными случаями использования, которые другие методы не могут легко разрешить. Я доволен расширением возможностей.

Также запрещает нам переходить на формат v3.x.

Мы сохраняем наши определения контейнеров докеров в макете «папка на экземпляр», где каждая папка содержит docker-compose.yml который определяет специфику env для экземпляра контейнера под рукой. Чтобы выделить общие вещи (DRY), мы используем определения базовых сервисов в родительской папке и используем extend .

Поэтому, когда мне нужно управлять конкретным экземпляром контейнера, мне просто нужно cd в нужную папку, и затем я могу напрямую запускать команды docker-compose без дополнительной настройки (никакие флаги -f требуются, чтобы члены команды нужно искать или знать, просто работает, как ожидалось, из коробки).

Мне запрещено использовать файлы для создания файлов версии 3.

Я использую services.yml для определения базового макета моих сервисов, а затем расширяю его с помощью dev.services.yml для моей среды разработки (в основном добавляя тома), но мне нравится (СУХОЕ) повторное использование расширений, когда это было добавлен. Это не нарушает условия сделки, но это удержит меня от перехода на версию 3, если в ней нет обязательной функции.

Я не против улучшения решения v2.1 'extends' чем-то более подходящим. Что-то вроде абстрактных сервисов может быть и более безопасным в использовании, и более мощным.

Например (поскольку это абстрактно), я мог бы представить поддержку абстрактных томов / точек монтирования / сетей, где абстрактная базовая служба определяет локальную точку монтирования или требуемую сеть для службы, не определяя часть хоста, то есть производная служба может затем определить / сопоставьте хост-часть монтировок / томов и сетей с тем, что подходит в его среде хоста / сцены.

Насколько мне известно, это пример того, что мы не можем сделать сейчас с «расширениями», и это открывает некоторые интересные возможности.

Отказ от функции расширения вообще не помог. У нас есть много веб-сервисов, запущенных с одинаковыми отображенными томами, установленными переменными среды и метками. У них также есть те же правила проверки работоспособности. И не говоря уже о портах. Объединение файлов компоновки с использованием нескольких параметров -f утомительно и чревато ошибками, если вы имеете дело с несколькими проектами на одном хосте.

@ shin - это будет возвращено в схему 3.2?

Мне очень, очень хотелось бы вернуть extends обратно в формат файла. Я использовал его для дальнейшего совершенствования абстрактных сервисов для ряда проектов. Я понимаю, что несколько вариантов -f почти полностью подходят, но это не всегда работает. Например, я довольно часто меняю имя абстрактной службы на что-то более значимое в контексте текущего проекта. Это то, что переопределение, которое происходит с несколькими параметрами -f , не поддерживает.

Я был бы не против потерять точную extends , если это какой-то другой способ "создать экземпляр" абстрактной службы в файле.

У меня есть установка с общим служебным файлом и кучей служб, расширяющих его, меняя в основном объемы, поэтому я бы сказал, что полагаюсь на функцию extends и не вижу другого хорошего способа описать мою установку.

--frustrated

+1
Я вижу логику, лежащую в основе рекомендации по сглаживанию файлов docker-compose, но мне не нравится идея дублирования кода, определяющего топологию нашей службы разработки, в нескольких проектах. На данный момент мы будем использовать обходной путь -f со сценариями оболочки, чтобы разработчикам не приходилось запоминать, какие службы в каких случаях включать.

Я надеюсь, что здесь можно найти удовлетворительное решение, позволяющее лучше разложить составные структуры на множители!

В верхней части моего списка вариантов использования находится DRYup для моего набора служб, управляемого конфигурацией. Я думал, что смогу воспользоваться расширением, если v3. Я не хочу возвращаться к v2 ... и не хочу иметь особых случаев, когда я должен использовать обход процесса -f.

Эй, кто-нибудь начал над этим работать? Я не могу найти PR, чтобы отслеживать. Это также упростило бы некоторые вещи для нас (вариант использования очень похож на некоторые, описанные выше).

Поскольку версия 3 заморожена, и мне нужен был способ поделиться общей конфигурацией, я взломал небольшой обходной путь, которым, думаю, я мог бы поделиться здесь (я не уверен, что это подходящее место, но не стесняйтесь сказать мне, где еще я могу поделитесь этой информацией :))

Я не буду здесь подробно останавливаться на этом, так как в репо есть файл readme.
Всем хорошего

Редактировать:

Извините, вот ссылка: D

+1

+1

+1

Спасибо за +1
Тем временем я нашел еще один образ docker noop , который меньше в 10 ^ 3 раз (из-за того, что фактический noop записывается в сборке).

К сожалению, в этом репо нет лицензии. Я уже писал владельцу сообщение на фейсбк, но он еще не ответил. Возможно, он добавит лицензию, если еще люди его спросят :)

Что-то, что может помочь в некоторых случаях использования расширений (в одном файле), будет поддержка якорей YAML: https://learnxinyminutes.com/docs/yaml/

Похоже, что схема JSON может не пройти проверку на них service must be a mapping, not a NoneType. .

Привет, @grayside , якоря yaml действительно работают, по крайней мере, для меня. См. Мой комментарий выше, чтобы узнать, как я их использую.

Хорошо, но слишком грустно пользоваться каким-то сервисом noop, нет?

Какие значения обрабатывают эти переменные env, особенно для переменных env? Если речь идет о секретах, используйте функцию секретов роя (или любое другое решение секретов). Если речь идет о настройках, мы в порядке, что в большинстве случаев настройки зависят от приложения / службы и не предназначены для совместного использования между службами.

Если вам нужно обмениваться настройками между службами, в большинстве случаев это происходит при запуске одного и того же образа контейнера, но для разных целей / задач времени выполнения (потребитель, производитель, http worker, ...).

Если речь идет о настройках, мы в порядке, что в большинстве случаев настройки зависят от приложения / службы и не предназначены для совместного использования между службами.

Я склонен не соглашаться. В проекте, над которым я сейчас работаю, я использую его, например, для томов:

# Volume paths
environment:
  - &volume_a        volume-a:/usr/share/my_project/volumes/volume-a
  - &volume_b        volume-b:/usr/share/my_project/volumes/volume-b
  - &volume_c        volume-c:/usr/share/my_project/volumes/volume-c
  - &volume_d        volume-d:/usr/share/my_project/volumes/volume-d

Теперь я могу указать эти объемы так:

volumes:
  - volume-a:
  - volume-b:
  - volume-c:
  - volume-d:

services:
  some-service:
    image: some-image
    volumes:
      - *volume_a
      - *volume_b

  some-other-service:
    image: some-other-image
    volumes:
      - *volume_b
      - *volume_c

  some-third-service:
    image: yet-another-image
    volumes:
      - *volume_a
      - *volume_b
      - *volume_c
      - *volume_d

Это упрощает навигацию по разным томам без необходимости думать о том, в каком контейнере вы находитесь. Имхо, это один из способов сделать вашу настройку docker-compose более последовательной, простой в использовании и обслуживании.

Хорошо, да, я понимаю @JanNash, но в вашем примере ниже у вас нет службы noop, верно?

Но во многих случаях якоря недостаточно.

В моем случае речь идет о поддержке нескольких сред для одного и того же проекта. Вы можете увидеть строительные леса для наших проектов здесь .

При разработке вы используете devel.yaml , но в производстве вы используете prod.yaml . Также есть test.yaml . Все они наследуются от common.yaml и получают некоторые общие переменные из файла .env .

У каждого свои особенности:

  • Среда devel нацелена на скорость разработки, поэтому она использует аргументы сборки, которые производят более быстрые сборки, монтирует тома с кодом приложения с компьютера разработчика и добавляет некоторые фиктивные службы, которые изолируют приложение от внешнего мира.
  • prod вместо этого нацелен на стабильность, поэтому он загружает и компилирует весь код и связывает его в самом образе вместо использования томов. Сборки медленнее, но безопаснее.
  • test стремится быть точно таким же, как prod, но с изоляцией от внешних сервисов, чтобы избежать загрязнения внешнего мира.

Это простое разделение позволяет иметь очень гибкий и гибкий конвейер DevOps, в котором все используют один и тот же код на разных этапах, с небольшими изменениями в зависимости от используемой среды.

Я попытался перейти к созданию формата файла v3, но не только extends не поддерживается, но и .env , так что сейчас это будет кошмар обслуживания (больше из-за отсутствия .env , если честно). При выборе между Swarm и DRY мы выбрали DRY на данный момент, но когда-нибудь нам понадобится Swarm, и я надеюсь, что в этот день обе функции снова будут поддерживаться ... ☺️

... или, по крайней мере, у нас есть способ сгенерировать действительный формат без DRY из решения с DRY. Я думал, что docker-compose bundle было для этого, но, похоже, сейчас он обречен на отказ ...

... или у нас есть другой инструмент, который все делает (я тоже слежу за ansible-контейнером ). Но, конечно, это не «исправление».

Ссылка в https://github.com/moby/moby/issues/31101#issuecomment -301212524 включает README с рабочим примером якорей YAML. Просматривая его и пробуя сегодня снова, он работает нормально. Не уверен, что делаю по-другому.

@JanNash 👍

@Yajo, я вас слышу, и, как уже говорилось, это обходной путь, и было бы на порядок лучше, если бы было хорошее встроенное решение DRY, поставляемое docker / moby / docker-compose (независимо от того, что является правильной ссылкой) . Будем надеяться, что это произойдет в ближайшее время, потому что, помимо этого, я очень доволен docker compose 👍

~ Ради отсутствия поддержки .env я также взломал обходной путь (мой проект еще не запущен в производство, так что мой доклад немного дешев, я знаю :)). Для поддержки различных наборов переменных окружения (например, версий / тегов зависимостей и изображений) в разных средах (для меня сейчас это локальная разработка и небольшой dev-сервер), я использую два файла: local.env и development.env и вместо того, чтобы выполнять свои команды с помощью всего docker-compose <command> , я либо передаю соответствующий файл .env в свою оболочку, либо запускаю его следующим образом: (. local.env && docker-compose <command>) . Все еще хакер, но пока меня это вполне устраивает. ~

Приятного вам дня

Может, даже на два порядка: D

@JanNash, подожди! .env больше не поддерживается в 3 ?

На самом деле не знаю, я только что прочитал в комментарии, что это не так.
Я использовал процедуры local.env и development.env в основном потому, что не знал об autoenv, когда реализовывал их: D
Извините за возможную путаницу.

Ах, @Yajo упомянул об отсутствии поддержки .env в этом комментарии .
Не могли бы вы уточнить, @Yajo?

Ой, извините, моя вина. Дело не в том, что он не работает, просто вы должны указать его с помощью env_file: .env , вместо того, чтобы обнаруживать его автоматически, как раньше. Вернемся к исходному вопросу.

Будет ли обсуждение куда-нибудь опустить extends ? Я бы с удовольствием прочитал его, прежде чем описывать наш пример использования, потому что я думаю, что он хорошо понимает, что это довольно часто используемая функция.

Привет, у меня один вопрос - когда? Когда "расширенная" поддержка вернется в v3?

@JanNash, вы можете получить намного меньше, чем это. Я только что подал в github проблему с вашим репо, у меня на моей машине не осталось 1200 байт с 750 КБ.

Я вижу, что в настоящее время в swarm я не могу использовать расширение.
есть идеи, как запустить одну и ту же службу с теми же портами публикации и с одним контейнером в службе, у которого есть 1 дополнительная переменная среды?

+1 за расширенную поддержку в развертывании стека роя

Привет,
Мы запускаем приложение микросервисов, которое распространяется в нескольких репозиториях git (каждый из которых имеет свой файл docker-compose).
Развертывание возглавляется одним «корневым» файлом docker-compose, который расширяет каждую службу: для нас эта функция extends действительно необходима для развертывания стека.
Так же +1 для расширения поддержки в развертывании стека роя.
Спасибо.

Вы можете использовать простое наследование YAML (см. &default , <<: *default ) в качестве временного решения:

version: '3'
services:
  worker: &default
    build: .
    command: bundle exec rake jobs:work
    env_file:
      - .env
    volumes:
      - .:/app
    depends_on:
      - db
      - redis
    links:
      - db:postgres
  web:
    <<: *default
    command: bundle exec puma -C config/puma.rb -p 3000
    ports:
      - "3000:3000"
  spring:
    <<: *default
    command: bundle exec spring server

Конечно, функция extends лучше

Как насчет того, чтобы расширить другой файл?

В Yaml нет функции расширения файлов :(

Есть ли какие-либо обновления по этой функции от участника Docker? Планируется ли это повторно ввести? Если нет, то есть ли в планах нечто подобное? Если нет, то почему бы и нет ..?

@quolpr , я боюсь, что ваш код "простого наследования YAML" в большинстве случаев не заменяет extends поскольку "прототип" (т.е. &default ) всегда будет интерпретироваться Docker Compose как сервис называется worker . Следовательно, какая услуга а) должна быть четко определена, б) может быть нежелательной.

Во всяком случае, определенно интересная особенность.

@laugimethods вы также можете использовать ссылки YAML:

version: '3'
services:
  spring:
    build: ./app
    command: /bin/sh -c "bundle exec spring server"
    volumes: &default_volumes
      - ./app:/app:delegated
      - bundle:/bundle:nocopy
  worker:
    build: ./app
    command: bundle exec sidekiq -v -C config/sidekiq.yml
    volumes: *default_volumes

(обратите внимание на &default_volumes и *default_volumes )

Но я действительно не могу понять, почему функция extends была удалена 🤔

К вашему сведению, чтобы заменить отсутствующую функцию «расширений», я теперь использую композицию / слияние файлов .yaml :
https://github.com/Logimethods/smart-meter/blob/master/README.md#docker -compose

extends работает, это просто и зрело, я думаю, что если кто-то видит в расширениях какой-то анти-шаблон, просто не используйте его, но, пожалуйста, не обрезайте его

Могу я попросить четкого объяснения предполагаемого подхода без использования extends ? Я широко использую его, особенно при наследовании файлов, содержащихся в подмодулях Git, что позволяет определить метапроект, обрабатывающий сетевые соединения между приложениями и т. Д. Хотя мне хорошо известно, что я могу указать несколько файлов docker-compose.yml и есть ли их переопределение, означает ли это, что мне нужно будет указать взаимосвязи в командной строке, вместо того, чтобы проверять их в системе управления версиями с помощью extends ? Или я пропустил какую-то новую функцию где-то в v3?

Я активно использую extends в нескольких проектах, чтобы наследовать общий набор атрибутов службы для разных сред и разных хостов (читайте: я использую extends для наследования от другого файла).

После прочтения в ступоре удаления ключевого слова extends и попытки найти замену, которая не требует последовательного соединения -f файлов компоновки докеров, мне очень любопытно, в чем причина удаления extends .

Я понимаю проблему с links и volume-from но мне кажется, что лучше всего просто отказаться от их использования в базовых файлах yml.

Было бы невероятно снять колесо с машины только потому, что оно _может_ привыкнуть переворачивать машину вверх ногами ... не так ли?

PS: noop и anchors выглядят интересно, но добавляют ненужной сложности самым простым проектам ...

В качестве очень и очень простого примера:

common/common.yml

services:
  web:
    image: alpine:3.6
    build: .
    environment:
      DOMAIN:
      PREFIX:

dev/docker-compose.yml

services:
  web:
    extends: ../common/common.yml
    service: web
  ports:
    - "8080:8080"

prod/docker-compose.yml

services:
  web:
    extends: ../common/common.yml
    service: web
  image: the-prod-image:latest-release
  ports:
    - "80:80"
    - "80:443"
  environment:
    NEW_RELIC_KEY:

Как соблюсти принципы DRY без extends ?

В настоящее время я не вижу причин для обновления с версии 2.1 из-за этого.

@teodorescuserban ,

шлейфовая цепочка -f docker компоновка файлов

Что с этим не так? Вы можете создавать свои собственные сценарии с короткими псевдонимами для вызова docker-compose.

Используйте следующую структуру:

общий / common.yml

services:
  web:
    image: alpine:3.6
    build: .
    environment:
      DOMAIN:
      PREFIX:

dev / docker-compose.yml

services:
  web:
    ports:
      - "8080:8080"

prod / docker-compose.yml

services:
  web:
    image: the-prod-image:latest-release
    ports:
      - "80:80"
      - "80:443"
    environment:
      NEW_RELIC_KEY:

Команды

docker-compose -f common/common.yml -f dev/docker-compose.yml -p myproject up --build
docker-compose -f common/common.yml -f prod/docker-compose.yml -p myproject up --build

Я не знал об этой особенности. Хотя это делает ваш CLI, он может работать.

Я думаю, что если это будет официальная замена extends , то должен быть способ сделать это проще.

Например:

docker-compose.yml

version: "3"  # or whatever
extend:
  - ./common/common.yml
  - ./dev/docker-compose.yml
services: # Not required now
  # etc.

Таким образом, вы можете указать один файл docker-compose.yml который делает все, что вам нужно.

Полезной альтернативой была бы поддержка нескольких файлов компоновки в переменной COMPOSE_FILE env.

@Yajo

Полезной альтернативой была бы поддержка нескольких файлов компоновки в переменной окружения COMPOSE_FILE.

Из https://docs.docker.com/compose/reference/envvars/#compose_file :

Эта переменная поддерживает несколько файлов Compose, разделенных разделителем пути (в Linux и macOS разделитель путей - : , в Windows - ; ). Например: COMPOSE_FILE=docker-compose.yml:docker-compose.prod.yml . Разделитель путей также можно настроить с помощью COMPOSE_PATH_SEPARATOR .

@ dermeister0 Вы также можете навсегда объединить эти файлы с помощью таких инструментов, как https://github.com/ImmobilienScout24/yamlreader :

> yamlreader common/common.yml prod/docker-compose.yml > docker-compose-prod.yml
> docker-compose -f docker-compose-prod.yml -p myproject up --build

> cat docker-compose-prod.yml
services:
    web:
        build: .
        environment:
            DOMAIN: null
            NEW_RELIC_KEY: null
            PREFIX: null
        image: the-prod-image:latest-release
        ports:
        - 80:80
        - 80:443

@ dermeister0 спасибо за ваше предложение, к сожалению, это неуклюжий выход. Использование extends устраняет необходимость действительно знать, как именно вам нужно их последовательно соединить. Хотя я могу жить с этим для себя, я никогда не смогу применить это решение к моим дорогим разработчикам.

Однако я не знал, что переменная COMPOSE_FILE env может содержать несколько значений. Спасибо @gsong ! Это круто, и я могу его использовать (я определяю это в файле .env ). Здесь есть одна единственная проблема: в базовых / общих файлах у меня также могут быть некоторые службы, которые мне не нужны.

Возьмем, к примеру, простой общий файл, определяющий базу данных и веб-контейнеры. При постановке вы хотите, чтобы все они были собраны вместе, но на продукте вам нужны отдельные хосты для db и для Интернета.

Кроме того, по умолчанию загружается docker-compose.override.yml.

https://docs.docker.com/compose/extends/#understanding -multiple-compose-files

Я использую этот подход с версией 3.3:

  • поместите общие параметры конфигурации и службы в docker-compose.yml ;
  • используйте docker-compose.override.yml для конкретной конфигурации разработки и служб (например, xdebug);
  • используйте docker-compose.staging.yml для конкретных опций конфигурации промежуточной стадии.

Примечание: я не запускаю Docker в производственной среде.

Используя этот подход, я могу легко создавать локально, используя docker-compose build и когда я развертываю на промежуточном этапе, я использую:

docker-compose -f docker-compose.staging.yml -f docker-compose.yml build

Я использую Apache, и у меня нет отдельных файлов виртуального хоста для разработки и размещения. Я потратил довольно много времени, чтобы не создавать разные файлы. В конце концов, я увидел, что единственный допустимый подход - это использование <IfDefine> и переменных среды (которые я установил в разделе окружения файлов yml), например, для включения конфигурации ssl. И я использую TLD и префикс домена, поэтому у меня может быть что-то вроде www.example.local http: //www.example.local/ : 8080 и www.staging.example.com http://www.staging.example.com / . Локально сайты работают по протоколу http, а на промежуточном уровне - по https. При таком подходе мне не нужно поддерживать разные версии файлов. Я думаю, что то же самое можно было бы сделать в производственной среде, но, как я уже сказал, я предпочитаю избегать Docker в производственной среде, atm.

Дорожки все родственники, поэтому контейнеры будут работать в любых условиях.

Мои 2 цента

-Филиппо

В моем случае раньше я использовал что-то вроде этого:

  • common.yml
  • devel.yml -> расширение common.yml
  • prod.yml -> расширение common.yml
  • docker-compose.yml -> local, git-ignored, символическая ссылка на желаемую среду (devel или prod).

Благодаря https://github.com/moby/moby/issues/31101#issuecomment -329482917 и https://github.com/moby/moby/issues/31101#issuecomment -329512231, о которых я не знал, теперь я могу перейти на v3, используя другую схему:

  • docker-compose.yml -> то, что раньше было common.yml
  • devel.yml -> переопределение docker-compose.yml
  • prod.yml -> переопределение docker-compose.yml
  • docker-compose.override.yml -> local, git-ignored, символическая ссылка на желаемую среду (devel или prod).

Я также могу делать любые необходимые хаки, используя переменную env, поэтому в моем случае проблема решена. Спасибо! 🎉 (Извините, я должен был внимательно прочитать новые документы, прежде чем жаловаться).

PS: Тем не менее, extends было бы неплохо вернуть, но, по крайней мере, у нас есть достаточно справедливая альтернатива. 😊

@ shin - Сначала я был очень разочарован, увидев, что функция extends отсутствует в 3.0 , но якоря YAML (пример: https://github.com/JanNash/docker-noop) будут замена более чем достаточная.

Единственное, что, как и в приведенном выше примере, вам нужно поместить свои якоря в какой-нибудь действительный раздел вашего файла docker-compose.yml .

Можем ли мы получить свойство (верхнего уровня) templates или скрытые ключи, как в GitLab, чтобы было более гибко определять привязки?

@ schmunk42 посмотрите https://github.com/docker/cli/pull/452

Проблема с использованием docker-compose.override.yml заключается в том, что он предполагает, что у вас есть только один тип переопределения, который вам нужно включить, и один уровень переопределений.

В моем случае я хочу иметь определенные поведения, общие для всех локальных разработок, но, возможно, они должны немного отличаться, если разработчик работает под Windows, OSX или Linux. Чтобы сохранить управляемость в контексте docker-compose v3, у меня есть пользователи Linux, которые работают с тем же поведением, что и промежуточная среда, что работает, но означает, что они немного не в ногу с другими разработчиками.

Я избегаю использования -f для локальной разработки, потому что я обнаружил, что он очень подвержен человеческим ошибкам, и полагаться на него как на переключатель для слишком многих вещей вызывает проблемы. Выбор одного файла кажется разумным, а выбор нескольких - это то, чего я стараюсь не навязывать.

FYI, я думаю , что когда - хак с x- упоминалось выше, а также последовательного подключения докеров-Compose файлов с помощью COMPOSE_FILE переменной в .env проекта файл, добавляющий docker- compose.override.yml должен решить все случаи использования, с которыми я сталкивался до сих пор.

Якоря yml - это тоже отличная вещь, которую я собираюсь использовать в ближайшем будущем.

Не очень доволен красотой хака x- но я могу с этим жить.

Спасибо, ребята, за ваш вклад!

Похоже, что удаление extends вызывает сильную изжогу и либо блокирует переход на v3, либо прибегает к взломам. Мне нравится возможность определять "шаблонную" (или абстрактную) службу, которая может нести некоторые общие вещи (например, политики обновления).

Я работаю над простой утилитой фильтра golang, которая может предварительно обработать файл компоновки докеров с помощью extends и выплюнуть чистый файл v3 с разрешенными расширениями:
решить-составить развертывание стека докеров -c docker-compose.yaml
(или docker-compose up)

Будет ли это работать хотя бы для некоторых из ваших вариантов использования / почему возникают проблемы?

@pnickolov Это было бы великолепно для меня.

Я искал ansible-контейнер (я использую ansible лично, но еще не на работе), который, похоже, сделает все, что мне нужно, но сценарий, подобный вашему, был бы более предпочтительным (меньше оттока)

Я был бы счастлив, если он может рекурсивно обрабатывать ключи extends: !

Хорошо, похоже, мы нашли альтернативы extends ... 👍

Что беспокоит, так это то, что Управление проектами Moby, похоже, не считает поддержание совместимости ключевым элементом. Прямая совместимость важна для более широкого внедрения, особенно для больших приложений, развернутых в производственной среде. Как мы можем продвигать Docker Swarm / Docker EE, если нет гарантии, что основные функции, такие как extends , останутся? 👎
Хорошую репутацию трудно завоевать и легко потерять ...

Лично я бы предпочел полагаться на собственные функции YAML для выполнения задачи, которая выполняется с помощью extends в синтаксисе v2 , а не на настраиваемый сценарий или более крупное решение, такое как ansible. Ранее у меня были похожие проблемы, и я начал писать свой собственный конвертер до того, как появилось решение вроде использования нескольких файлов .yml и т. Д. (Https://github.com/schmunk42/yii2-yaml-converter-command) - но это не так жизнеспособное решение.

Для меня также нормально отказаться от функций, если это делается вместе с политикой управления версиями; Вы не можете носить старые вещи вечно, даже если это означает, что нам придется поработать.

@ schmunk42 Устаревшие функции - это нормально, но только если:

  • удаленная функция больше не используется или является реальным препятствием для эволюции
  • это объявляется заранее
  • сразу предоставляется путь миграции

К сожалению, ни одно из этих требований (в моей книге) не относится к устареванию extends ...

@laugimethods. По какой причине вам нужно использовать v3 ?

@ schmunk42 Из-за Swarm:

Версия 3.x, последняя и рекомендуемая версия, предназначена для перекрестной совместимости между Compose и режимом swarm Docker Engine. Это указывается с версией: '3' или версией: '3.1' и т. Д., Записью в корне YAML.

Команда docker stack deploy поддерживает любой файл Compose версии «3.0» или выше.

Кстати, мой комментарий связан не только с extends , но и с любым (болезненным) отказом от поддержки, которое может произойти в будущем ...

Да, мы сталкиваемся с той же проблемой из-за режима роя.

Я прежде всего спросил себя, какого черта интерфейс командной строки докеров теперь может использовать --composer-file input. Но, судя по нашему опыту работы с docker/swarm , запуск стеков в (самоуправляемом) рое выглядит довольно сложной задачей, и есть несколько веских причин, по которым это было перемещено в движок.

Просто чтобы отметить некоторые из моих выводов здесь ... переход от v2 к v3.4 далеко не прост.

Некоторые из моих проблем:

  • есть и другие неподдерживаемые параметры, такие как volumes_from , которые довольно легко обойти, так как мы все равно хотели удалить их
  • .env files (например, docker-compose ) не работают с Docker CLI
  • указание нескольких файлов для компоновки ( docker stack deploy -c docker-compose.yml -c docker-compose.override.yml doro ), похоже, не работает правильно, ошибки нет, но мне кажется, что они также неправильно объединены - но также нет такой команды, как docker-compose config чтобы проверить это
  • для docker-compose который поддерживает синтаксис v3.4 , не существует "простого в установке" (предварительного выпуска) двоичного файла; как край докера
  • внешние сети должны быть созданы с помощью --scope swarm

CC: @handcode

Использование последних сборок

  • докер 17.09.0-ce
  • докер-составить 1.17.0dev

Теперь я использую этот конвейер конфигурации, чтобы заменить использование _extend_ и _noop_
Сохраняет сухость вещей
Надеюсь, это кому-то поможет

base.yml (общие определения, это действительный документ yaml, поэтому его можно объединить с помощью _docker-compose config_)

version: '3.4'
networks:
  net_back:
    external: true

base-inject.yml (общие определения base.yml, поскольку на привязки нельзя ссылаться в разных файлах yaml, вместо этого они вводятся как текст в foo.yml , что не является идеальным способом для этого)

x-logging: &logging
  driver: json-file
  options:
    max-size: "50m"
    max-file: "2"

foo.yml (общее определение стека, ссылки на объекты из base.yml , якоря из base-inject.yml и объекты, переопределенные в foo-dev.yml )

version: '3.4'
[[base-inject]]
services:
  foo:
    image: ${DOCKER_REGISTRY}/foo:${IMAGE_VERSION}
    volumes:
      - type: volume
        source: "volfoo"
        target: "/foo"
    networks:
     - net_back
    logging:
      <<: *logging

foo-dev.yml (для определения стека среды)

version: '3.4'
services:
  foo:
    ports:
      - "8080:80"
volumes:
  volfoo:
    name: '{{index .Service.Labels "com.docker.stack.namespace"}}_volfoo_{{.Task.Slot}}'
    driver: local

Затем команда развертывания:

docker stack rm stack_foo && echo "waiting..." && sleep 3 &&
  cat foo.yml | sed -e '/base-inject/ {' -e 'r base-inject.yml' -e 'd' -e '}' > ./foo-temp1.yml &&
  export $(sed '/^#/d' ./dev.env | xargs) &&
  docker-compose -f base.yml -f ./foo-temp1.yml -f foo-dev.yml config > ./foo-temp2.yml
  docker stack deploy --with-registry-auth --prune --compose-file ./foo-temp2.yml stack_foo
  1. Удалить старую стопку
  2. Подождите, пока съемный стек начнет распространяться
  3. Вставить якоря в общее определение, сохранить в файл tmp
  4. Чтение + установка переменных файла env из файла
  5. Используйте docker-compose, чтобы объединить три файла вместе
  6. Развернуть объединенный файл

Для тех из вас, кто жаждет extends в составлении 3+ файлов, я только что взял в руки инструмент под названием baclin . baclin линеаризует такие директивы, рекурсивно заменяя все директивы extends их содержимым. Это альфа-версия программного обеспечения, код является частью моего оборудования, поскольку в настоящее время я пишу код для поддержки режима Swarm и развертывания стеков. Бинарные файлы платформы ранней версии baclin доступны здесь . Пожалуйста, сообщайте о любых комментариях или проблемах здесь .

Это действительно сбивает с толку!
Эта функция должна быть доступна при чтении документации для последней версии докера ( v17.09 ), а также документа v17.06 release .

$ head -n1 docker-compose.yml
version: '3'

Но compose up дает

ERROR: The Compose file './docker-compose.yml' is invalid because:
Unsupported config option for services.admin_application: 'extends'

при использовании ключевого слова extends .
Кроме того, я не могу найти ничего об удалении extends в журнале изменений compose .

Что это теперь ?!
Важную информацию, подобную этой, нетрудно найти или спрятать в какой-то неясной проблеме с github.


$ docker --version
Docker version 17.09.0-ce, build afdb6d4

$ docker-compose --version
docker-compose version 1.16.1, build 6d1ac21

@jottr , см. документы :

Ключевое слово extends поддерживается в более ранних форматах файлов Compose до версии файла Compose 2.1 (см. Extends в v1 и extends в v2), но не поддерживается в Compose версии 3.x.

Поэтому, если вы хотите использовать extends вам нужно придерживаться version: '2.1' .

Виноват. Он по-прежнему должен быть вверху документа с красным предупреждающим знаком об устаревании.

Виноват. Он по-прежнему должен быть вверху документа с красным предупреждающим знаком об устаревании.

@jottr Просто используйте Github, чтобы создать отдельный выпуск для этого или даже создать PR для этого. Только что создал проблему: https://github.com/docker/docker.github.io/issues/5340

В моем случае у меня есть docker-compose-override.yml как показано ниже:
yaml version: "3.4" services: common: extra_hosts: - "host1:172.28.5.1" - "host2172.28.5.2" - "host3:172.28.5.3" networks: default: external: name: "common-network"
И у меня есть несколько других файлов docker-compose.yml которым нужно совместно использовать сеть и extra_hosts. Как это сделать, используя функцию без расширений?

yaml version: "3.4" services: mongo: image: "mongo" container_name: "mongo" hostname: "mongo" volumes: - "/opt/docker/mongo/default.conf:/usr/local/etc/mongo/mongod.conf" - /opt/data/mongo:/data/db" ports: - "27017:27017" command: "mongod --config /usr/local/etc/mongo/mongod.conf" networks: default: ipv4_address: "172.28.5.4"
Было бы здорово, если бы docker-compose поддерживал привязку yaml и ссылки между разными файлами. Возможно, применяя якорь и ссылки после слияния файлов.
Например:
yaml version: "3.4" services: common: &common extra_hosts: ... networks: ...
yaml version: "3.4" services: mongo: <<: *common image: "mongo" container_name: "mongo" ...
Результат должен быть:
yaml version: "3.4" services: mongo: image: "mongo" container_name: "mongo" extra_hosts: // EXTRA HOSTS HERE networks: ...

@ sandro-csimas это возможно с помощью: https://docs.docker.com/compose/compose-file/#extension -fields
@ shin- можно ли закрыть этот билет?

@rdxmb Я так не думаю. Насколько я понимаю, вы не можете расширяться из другого файла для создания докеров.

Правильно ли я думаю, что это проблема https://github.com/docker/compose/issues ?

Некоторая отладка:

# cat docker-compose.yml 
version: "3.4"
services:
  foo-not-bar:
    << : *common
  foo-bar:
    << : *common
    environment:
      - FOO=BAR 

x-common-definitions-for-all-our-services:
  &common
    image: phusion/baseimage
    environment:
      - FOO=NOTBARBYDEFAULT

Это работает с
docker stack deploy -c docker-compose.yml test

При использовании docker-compose:

# docker-compose up 
ERROR: yaml.composer.ComposerError: found undefined alias 'common'
  in "./docker-compose.yml", line 4, column 10

Изменение yml-файла на:

version: "3.4"

x-common-definitions-for-all-our-services:
  &common
    image: phusion/baseimage
    environment:
      - FOO=NOTBARBYDEFAULT

services:
  foo-not-bar:
    << : *common
  foo-bar:
    << : *common
    environment:
      - FOO=BAR

также работает с docker-compose.

Поэтому подумал, что это также должно работать с несколькими файлами, что не так:

# docker-compose -f compose-services.yml -f compose-default.yml config > docker-compose.yml
ERROR: yaml.composer.ComposerError: found undefined alias 'common'
  in "./compose-services.yml", line 5, column 10
t# docker-compose -f compose-default.yml -f compose-services.yml config > docker-compose.yml
ERROR: yaml.composer.ComposerError: found undefined alias 'common'
  in "./compose-services.yml", line 5, column 10
# cat compose-services.yml 
version: "3.4"

services:
  foo-not-bar:
    << : *common
  foo-bar:
    << : *common
    environment:
      - FOO=BAR 

# cat compose-default.yml 
x-common-definitions-for-all-our-services:
  &common
    image: phusion/baseimage
    environment:
      - FOO=NOTBARBYDEFAULT

Однако, конечно, это возможно с помощью простого использования cat :

# cat compose-default.yml compose-services.yml > docker-compose.yml && docker-compose up -d
WARNING: The Docker Engine you're using is running in swarm mode.

Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.

To deploy your application across the swarm, use `docker stack deploy`.

Creating network "test_default" with the default driver
Creating test_foo-bar_1 ... 
Creating test_foo-not-bar_1 ... 
Creating test_foo-bar_1
Creating test_foo-bar_1 ... done

Работает на xenial с версиями:

# docker --version
Docker version 17.11.0-ce, build 1caf76c
# docker-compose --version
docker-compose version 1.17.0, build ac53b73

@rdxmb , спасибо!
Итак, я должен объединить файлы compose с помощью команды «cat» и запустить окончательный файл.

Я также использую для этого docker-compose config . Пример настроек для конкретной среды:

Это выполняется конвейером CI: docker-compose -f docker-compose.yml -f docker-compose.override.prod.yml config > docker-compose.prod.yml а затем я использую docker stack deploy -c .\docker-compose.prod.yml my-stack

Проголосуйте за это, расширение очень полезно для v3.

Много использовал его с v2, действительно очень полезно!
+1

Я бы хотел увидеть поддержку extends в v3. Это очень помогло бы ОСУШИТЬ мой файл docker-compose.yml .

С момента появления этой проблемы прошел почти год, и действительно очевидно, что эта функция нужна тонне людей. Тем не менее, я не читал, чтобы разработчик Docker ответил на этот запрос, или объяснил, почему он не был включен в docker-compose v3 перед выпуском.

Печальное состояние программного обеспечения, если мы даже не можем общаться или поддерживать функции для наших клиентов, которые верят в новую технологию.

Одна из возможных интерпретаций (и, возможно, также краткое изложение текущего потока) ситуации выглядит следующим образом:

  • Якоря / ссылки YAML плюс поля расширения 3.4 достигают почти того же.
  • многофайловый можно заставить работать. См. Простой cat и расширенный подход в этой теме. Комментарий к простому подходу показывает проблему загрузки нескольких файлов docker-compose в конце (кто-нибудь создал для этого проблему?). Если бы это было исправлено в docker-compose, вам вообще не понадобилось бы слияние файлов. Поэтому для меня люди, желающие поддерживать многофайловую поддержку, должны продолжать работу в docker / compose / issues, как предлагает @rdxmb .
  • Рассматривался вопрос о возврате extends (см. События проекта GitHub , хорошая прозрачность здесь от команды Docker, спасибо!), И вы можете интерпретировать результат как «есть множество других вещей, которые стратегически более важны для них», но вы можете все еще напишу запрос на перенос для extends я думаю.

Для меня это совершенно понятная точка зрения.

@aCandidMind Согласен.

IMHO, хотя подходы, упомянутые @aCandidMind, работают, они добавляют сложности к более простому и понятному механизму, предоставляемому extends .
Может быть, это я, но перенос умеренно сложной конфигурации расширений в поля расширений становится намного сложнее читать и поддерживать.
После прочтения множества комментариев и сообщений мне все еще неясно, почему были отброшены расширения и каковы преимущества этого регресса в возможностях.

Возможно, с помощью небольшой магии bash я подготовил тестовое репо, чтобы вы могли попробовать его сами.

Просто структурируйте свою команду stack deploy следующим образом:

docker stack deploy --compose-file=<(docker-compose -f docker/prod.yml -f docker/dev.yml config) <stackname>

@tylerbuchea - единственный недостаток этой магии bash в том, что вы можете получить WARNING: Some services (<service-name(s)>) use the '<key>' key, which will be ignored. Compose does not support '<key>' configuration . Это может вызвать некоторую путаницу. Но эй, это работает 👍

@dnmgns ты прав! Спасибо что подметил это. Как сказал @joaocc, ничто не

@tylerbuchea Один грязный способ - просто перенаправить stderr на / dev / null :)
docker stack deploy --compose-file=<(docker-compose -f docker/prod.yml -f docker/dev.yml config 2> /dev/null) <stackname>

В этом нет ничего постыдного 😄

Я думаю, что документация должна более подробно описывать эту путаницу вокруг extend .
Описание extend перенаправляет пользователя к документам с инструкциями по обновлению, а документы с инструкциями по обновлению указывают обратно на описание extend для получения дополнительной информации. Это недостаточно полезно: как пользователь я бы ожидал некоторой помощи, как справиться со всей этой проблемой, какие варианты у меня есть и что мне следует рассмотреть. Я уверен, что решение об удалении extend из v3 было ясным.

Видеть:
https://docs.docker.com/compose/extends/#exnding -services
https://docs.docker.com/compose/compose-file/compose-versioning/#upgrading

Что касается отличного однострочного решения на основе bash
к сожалению, он не поддерживает некоторые расширенные функции стека Docker:

WARNING: Some services (web) use the 'deploy' key, which will be ignored. Compose does not support 'deploy' configuration - use `docker stack deploy` to deploy to a swarm.
WARNING: Some services (web) use the 'configs' key, which will be ignored. Compose does not support 'configs' configuration - use `docker stack deploy` to deploy to a swarm.

Не то чтобы с тех пор, как https://github.com/docker/cli/pull/569 был объединен, начиная с 18.03, docker stack deploy будет поддерживать объединение нескольких составных файлов в один. Он не полностью заменяет ключ extends из формата composefile v2, но, надеюсь, покрывает гораздо больше вариантов использования 👼

Мой собственный обходной путь заключался в использовании yq (может быть объединен в однострочник при использовании Bash):

yq merge --overwrite docker-stack.yml docker-stack.preprod.yml > merged-docker-stack.yml
docker stack deploy -c merged-docker-stack.yml preprod

@ Lucas-C они просто предупреждают, что вывод все еще будет включать ваши ключи deploy и config . Вы можете проверить это, запустив docker-compose -f docker/prod.yml -f docker/dev.yml config

Он предназначен для создания файлов v3.4 и выше. Он поддерживает перекрестные ссылки yaml (частичные). Я закончил с этим псевдонимом zsh / скриптом perl:

alias regen=$'perl -MFile::Slurp=read_file -MYAML=Load,Dump -MHash::Merge::Simple=merge -E \'
  local $YAML::QuoteNumericStrings = 1;
  $n=read_file("/data/docker-compose.yml");
  $s=Dump(merge(map{Load($n.read_file($_))}@ARGV));
  local $/ = undef;
  $s =~ s/\\bno\\b/"no"/g;
  say $s;
  \' $(find /data -mindepth 2 -maxdepth 4 -name docker-compose.yml) >! /data/x-docker-compose.yml'
regen
export COMPOSE_FILE=/data/x-docker-compose.yml
  1. прочтите /data/docker-compose.yml с общей частью.
  2. найти все docker-компоновки рекурсивно (например, в этом проекте около 40 различных файлов контейнеров / docker-compose.yml)
  3. добавьте к каждому docker-compose.yml содержимое /data/docker-compose.yml
  4. слить
  5. сохранить результат в /data/x-docker-compose.yml

Плюсы : Perl - обычный инструмент, все модули Perl тоже, генерация выполняется быстро.
Минусы : ненавижу хаки, но для DRY другого выхода нет. Окончательный docker-compose составляет около 900 строк. Вы действительно хотите, чтобы я поддерживал его как единый файл с самого начала? Жалко иметь двоичный докер, обернутый python docker-compose, обернутый perl hack.

Как можно просто убрать такую ​​функцию, как extends? Это похоже на ключевую особенность.

Использование docker-compose config подключенного к стандартному параметру ввода docker stack deploy -c - , решило для меня проблему:

docker-compose -f docker-compose.yml \
               -f docker-compose.extended.yml \
               config \
| docker stack deploy -c - my-stack

Я не пробовал этого, но я просто заметил это в документации docker stack deploy :

Если ваша конфигурация разделена между несколькими файлами Compose, например базовой конфигурацией и переопределениями, зависящими от среды, вы можете указать несколько флагов --compose-file .

В качестве примера:

docker stack deploy --compose-file docker-compose.yml -f docker-compose.prod.yml vossibility

https://docs.docker.com/engine/reference/commandline/stack_deploy/#compose -file

Задокументировано ли где-нибудь обоснование удаления extends ? Кажется, это не объясняется в официальных документах, например здесь: https://docs.docker.com/compose/extends/#exnding -services
Если бы пользователи могли понять причину удаления, они могли бы лучше понять, как реагировать на удаление. Спасибо.

@ shaun-blake В итоге я использовал несколько файлов для создания файлов. Кажется, что это тот подход, который используют люди. Это больше похоже на смешение, чем на наследование. При сборке или запуске я копирую правильный шаблон yaml среды в docker-compose.override.yml.

Несколько файлов компоновки докеров (например: base.yml , local.yml , prod.yml ) не позволяют службе использовать якоря YAML из других файлов, поэтому факторизованные определения службы не могут быть определены среди нескольких файлов yml .
Обратите внимание: эта проблема занимает 13-е место по количеству комментариев : https://github.com/moby/moby/issues?q=is%3Aissue+is%3Aopen+sort%3Acomments-desc и 3-е место по популярности .

Если бы пользователи могли понять причину удаления, они могли бы лучше понять, как реагировать на удаление. Спасибо.

+1 к документации по обоснованию удаления extends в первую очередь ...

Спустя почти полтора года все еще нет _extends_. Да ладно, разработчики, вы не удаляете что-то, не указав альтернативы.

Они сделали, они предлагают альтернативу, называемую композицией. Пожалуйста, прочтите мой ответ в ветке.

-Филиппо

30 июля 2018 года в 09:41 Xiaohui Liu [email protected] написал:

Спустя почти полтора года все еще нет продлений. Да ладно, разработчики, вы не удаляете что-то, не указав альтернативы.

-
Вы получили это, потому что прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub https://github.com/moby/moby/issues/31101#issuecomment-408790200 или отключите поток https://github.com/notifications/unsubscribe-auth/AAS_0AOynjpfVnVnVo4ZqciMbmjBmkcLMb4ks .

@dedalozzo , "в теме" ==?

Пожалуйста, посмотрите мой комментарий здесь:

https://github.com/moby/moby/issues/31101#issuecomment -329527600 https://github.com/moby/moby/issues/31101#issuecomment-329527600

В основном вам нужно использовать цепочку файлов .yml, чтобы переопределить или изменить конфигурацию ваших контейнеров.

Пожалуйста, прочтите «Указание нескольких файлов Compose»

Вы можете указать несколько файлов конфигурации -f. Когда вы предоставляете несколько файлов, Compose объединяет их в единую конфигурацию. Compose строит конфигурацию в том порядке, в котором вы предоставляете файлы. Последующие файлы отменяют и добавляют к своим предшественникам.

https://docs.docker.com/compose/reference/overview/ https://docs.docker.com/compose/reference/overview/

Этот подход использует композицию вместо наследования для получения более или менее того же результата.

30 июля 2018 года в 15:23 Сербан Теодореску [email protected] написал:

@dedalozzo https://github.com/dedalozzo , "в ветке" ==?

-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub https://github.com/moby/moby/issues/31101#issuecomment-408880809 или отключите поток https://github.com/notifications/unsubscribe-auth/AAS_0FZO30NplqHRid_Id8VBOJW7cmlk5 .

Разве мы не сможем вернуть такую ​​же расширяемость, если объединим
поля расширения yaml (составляют 2.1 + / 3.4 +)
с разрешением этим полям x- ссылаться на другие файлы ?

Таким образом, мы могли позволить корневому списку include указывать файлы для загрузки.
они будут помещены в x-include и будут мгновенно использованы через стандартные якоря YAML и слияние.



Текущая версия compose v2.1 +
# /docker-compose.yml
version: '2.1'

volumes:
  nginx_file_sockets:
    external: false
    driver: local

services:
  reverse_proxy:
    extends:
      file: reverse_proxy/docker-compose.yml
      service: proxy
    restart: 'always'
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - nginx_file_sockets:/sockets/nginx

  reverse_proxy_test:
    extends:
      file: reverse_proxy/docker-compose.yml
      service: proxy
    restart: 'always'
    ports:
      - "8080:80"
      - "8443:443"
    volumes:
      - nginx_file_sockets:/sockets/nginx

  web:
    extends:
      file: webservice/docker-compose.yml
      service: app
    restart: 'always'
    environment:
      ENVIRONMENT: 'production'
      DB_USER: ${WEB1_DB_USER}
      DB_PASSWORD: ${WEB1_DB_PASS}
    volumes:
      - nginx_file_sockets:/sockets/nginx

  web_staging:
    extends:
      file: webservice/docker-compose.yml
      service: app
    restart: 'no'
    environment:
      ENVIRONMENT: 'staging'
      DB_USER: ${WEB1_DB_USER}
      DB_PASSWORD: ${WEB1_DB_PASS}
    volumes:
      - nginx_file_sockets:/sockets/nginx

# /proxy/docker-compose.yml
version: '2.1'
services:
  proxy:
    build: ./
    volumes:
      - /certs:/certs:ro
# /webservice/docker-compose.yml
version: '2.1'
services:
  app:
    build:
      context: ./folder
      args:
        LINUX_VERSION: 20.s
        LINUX_FLAVOR: dash
    environment:
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - bootstrap.memory_lock=true
    ulimits:
      memlock:
        soft: -1
        hard: -1




Идея compose v3.X
# /proxy/docker-compose.yml
version: '3.9'
services:
  proxy:
    &proxy
    build: ./
    volumes:
      - /certs:/certs:ro
# /webservice/docker-compose.yml
version: '3.9'
services:
  app:
    &app
    build:
      context: ./folder
      args:
        LINUX_VERSION: 20.s
        LINUX_FLAVOR: dash
    environment:
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - bootstrap.memory_lock=true
    ulimits:
      memlock:
        soft: -1
        hard: -1
# /docker-compose.yml
version: '3.9'
include:
  - /proxy/docker-compose.yml
  - /webservice/docker-compose.yml

volumes:
  nginx_file_sockets:
    external: false
    driver: local

services:
  reverse_proxy:
    << : *proxy
    restart: 'always'
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - nginx_file_sockets:/sockets/nginx

  reverse_proxy_test:
    restart: 'always'
    << : *proxy
    ports:
      - "8080:80"
      - "8443:443"
    volumes:
      - nginx_file_sockets:/sockets/nginx

  web:
    << : *app
    restart: 'always'
    environment:
      ENVIRONMENT: 'production'
      DB_USER: ${WEB1_DB_USER}
      DB_PASSWORD: ${WEB1_DB_PASS}
    volumes:
      - nginx_file_sockets:/sockets/nginx

  web_staging:
    restart: 'no'
    extends:
      file: web1/docker-compose.yml
      service: app
    environment:
      ENVIRONMENT: 'staging'
      DB_USER: ${WEB1_DB_USER}
      DB_PASSWORD: ${WEB1_DB_PASS}
    volumes:
      - nginx_file_sockets:/sockets/nginx




Diff
@@ /proxy/docker-compose.yml @@
-version: '2.1'
+version: '3.9'
 services:
   proxy:
+    &proxy
     build: ./
     volumes:
       - /certs:/certs:ro
 ```

 ```diff
 @@ /webservice/docker-compose.yml @@
-version: '2.1'
+version: '3.9'
 services:
   app:
+    &app
     build:
       context: ./folder
       args:
         LINUX_VERSION: 20.s
         LINUX_FLAVOR: dash
     environment:
       - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
       - bootstrap.memory_lock=true
     ulimits:
       memlock:
         soft: -1
         hard: -1
 ```

 ```diff
 @@ /docker-compose.yml @@
-version: '2.1'
+version: '3.9'
+include:
+  - /proxy/docker-compose.yml
+  - /webservice/docker-compose.yml

 volumes:
   nginx_file_sockets:
     external: false
     driver: local

 services:
   reverse_proxy:
-    extends:
-      file: reverse_proxy/docker-compose.yml
-      service: proxy
+    << : *proxy
     restart: 'always'
     ports:
       - "80:80"
       - "443:443"
     volumes:
       - nginx_file_sockets:/sockets/nginx

   reverse_proxy_test:
-    extends:
-      file: reverse_proxy/docker-compose.yml
-      service: proxy
+    << : *proxy
     restart: 'no'
     ports:
       - "8080:80"
       - "8443:443"
     volumes:
       - nginx_file_sockets:/sockets/nginx

   web:
-    extends:
-      file: webservice/docker-compose.yml
-      service: app
+    << : *app
     restart: 'always'
     environment:
       ENVIRONMENT: 'production'
       DB_USER: ${WEB1_DB_USER}
       DB_PASSWORD: ${WEB1_DB_PASS}
     volumes:
       - nginx_file_sockets:/sockets/nginx

   web_staging:
-    extends:
-      file: webservice/docker-compose.yml
-      service: app
+    << : *app
     restart: 'no'
     environment:
       ENVIRONMENT: 'staging'
       DB_USER: ${WEB1_DB_USER}
       DB_PASSWORD: ${WEB1_DB_PASS}
     volumes:
       - nginx_file_sockets:/sockets/nginx
 ```
<hr>
Resulting in the final version, which should be already yaml parsable:

```yml
# /docker-compose.yml
version: '3.9'
#include:
#  - /proxy/docker-compose.yml
#  - /webservice/docker-compose.yml
x-include:
  /proxy/docker-compose.yml:
    version: '3.9'
    services:
      proxy:
        &proxy
        build: ./
        volumes:
          - /certs:/certs:ro
  /webservice/docker-compose.yml:
    version: '3.9'
    services:
      app:
        &app
        build:
          context: ./folder
          args:
            LINUX_VERSION: 20.s
            LINUX_FLAVOR: dash
        environment:
          - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
          - bootstrap.memory_lock=true
        ulimits:
          memlock:
            soft: -1
            hard: -1

volumes:
  nginx_file_sockets:
    external: false
    driver: local

services:
  reverse_proxy:
    << : *proxy
    restart: 'always'
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - nginx_file_sockets:/sockets/nginx

  reverse_proxy_test:
    << : *proxy
    restart: 'no'
    ports:
      - "8080:80"
      - "8443:443"
    volumes:
      - nginx_file_sockets:/sockets/nginx

  web:
    << : *app
    restart: 'always'
    environment:
      ENVIRONMENT: 'production'
      DB_USER: ${WEB1_DB_USER}
      DB_PASSWORD: ${WEB1_DB_PASS}
    volumes:
      - nginx_file_sockets:/sockets/nginx

  web_staging:
    << : *app
    restart: 'no'
    environment:
      ENVIRONMENT: 'staging'
      DB_USER: ${WEB1_DB_USER}
      DB_PASSWORD: ${WEB1_DB_PASS}
    volumes:
      - nginx_file_sockets:/sockets/nginx

AFAIK, это функция YAML, встроенная в саму спецификацию laguage, чтобы избежать повторения частей в одном файле. При использовании разных файлов это в принципе невозможно.

Вы должны предложить эту функцию в самой спецификации YAML.

Это обсуждение сводится к следующему:

  • Чем docker-compose -f file.yml намного лучше, чем docker-compose -f file.yml -f file_extension.yml ?
  • Или: подключение на уровне команд _vs_ подключение на уровне файлов.

Только при работе в командной строке неудобство становится ощутимым. Мы должны признать это на секунду. Во всяком случае, все остальное можно использовать в сценариях.

Если это реальный аргумент, то семантика docker-compose up service лучше, чем docker-compose -f service.yml up : в docker-compose.override.yml определите все, что необходимо для локальной разработки (то есть в командной строке).

Данная семантика очень чистая и хорошо продуманная. Принятие service.yml _ для использования в командной строке, вероятно, означает снижение UX. Есть еще один аргумент: хотя с первого взгляда ясно, что такое docker-compose.yml , service.yml может быть чем угодно, действительно чем угодно.

Отказ от ответственности: провокационное мнение. : wink: Я не учел все возможные варианты использования ...

После этого продолжительного обсуждения не уверен, выйдет ли оно когда-нибудь. ИМХО, расширение было круто и должно быть, по крайней мере, было тщательно устаревшим, а затем обсуждалось вместо того, чтобы просто отказаться от него.

Я думаю, что мы могли бы улучшить документацию по v2 и v3. Многие считают, что v3 заменил v2, но это не совсем так. Оба получают новые функции, ориентированные на их варианты использования. Эта проблема GH была начата, чтобы мы могли обсудить, какие будущие функции необходимы для перехода от docker-compose к Swarm, и как улучшить документацию для использования docker-compose, формата файла compose и стеков Swarm вместе. Расширения по-прежнему отлично работают в последней версии 2.4. Надеюсь, я смогу предложить информацию о том, какие решения у нас есть сегодня:

v2: только для docker-compose cli. Рабочий процесс разработки сосредоточен на одной машине и двигателе. Также подходит для рабочих процессов сборки / тестирования CI. Эта ветка версии получила новые функции совсем недавно, начиная с декабря 2017 года, в версии 17.12.

v3: Идеально подходит для стеков Swarm / Kube, с концепцией многоузловых и поддерживает большинство функций docker-compose cli.

Если вы не используете стеки Swarm или Docker Enterprise Kubernetes, нет причин использовать v3 . Придерживайтесь версии 2.4, и вы получите все возможности cli для создания докеров, включая extends, depends_on, extension fields и даже depends_on с проверками работоспособности (чтобы избежать сценариев ожидания).

v3 был создан, чтобы попытаться объединить функции мира cli docker-compose с одним движком и миром многоузлового кластера. Не все функции v2 (например, depends_on) имеют смысл в кластере. Другие функции (например, extension) просто не вошли в v3, вероятно, потому что до того, как v3 существовала, весь код был на Python с docker-compose, а для v3.0 для поддержки Swarm им пришлось переписать это в docker cli Go, и теперь они снова пишут это в демоне движка, чтобы в конечном итоге создать API стеков Swarm, которого пока не существует.

Для тех, кто не знаком с этой проблемой, также обратите внимание на большую часть работы, которая была проделана для решения различных проблем с конфигурацией, шаблонами и рабочими процессами группы, начиная с версии 3.0:

В документации по адресу https://docs.docker.com/compose/extends/#exnding -services должен быть выделен красным цветом тот факт, что ключевое слово extends удалено в версии 3, поскольку оно более важно, чем просто _note_.
Я перенес и просмотрел документы, чтобы выяснить, почему он больше не работает, затем изучил несколько закрытых проблем, прежде чем оказался здесь, затем вернулся к исходным документам и заметил формулировку.

Ключевое слово extends поддерживается в более ранних форматах файлов Compose до версии файла Compose 2.1 (см. Extends в v1 и extends в v2), но не поддерживается в Compose версии 3.x.

Можно перефразировать так:

Ключевое слово extends было удалено в Compose версии 3.x, но по-прежнему поддерживается в более ранних форматах файлов Compose до версии Compose файла 2.1 (см. Extends в v1 и extends в v2).

Это небольшая разница, но ее легко упустить, просматривая документы.

@krisrp PR начался ^^^

Спасибо @BretFisher

Есть ли планы переименовать v2 в «version: docker-cli» и v3 в «version: swarm / kube»?
Было бы разумнее различать их таким образом, учитывая, как v3 заменяет v2 в большинстве других схем управления версиями. В настоящее время оба поддерживаются и расходятся, поэтому, если я не ошибаюсь, кажется, что они оба будут какое-то время.

@krisrp Напротив, причина увеличения номера основной версии состоит в том, чтобы сигнализировать о расхождении в совместимости.

@ cpuguy83 Я не имел в виду иное. Приносим извинения за неясность и ясность.
У IIRC Gnome 2 и 3 тоже была эта путаница много лет назад, когда поддерживались независимые форки каждого из них.

Я не хочу мешать обсуждению семантики управления версиями (плохой каламбур), поэтому оставлю все как есть. Сообщение @BretFisher на прошлой неделе об улучшении документации по v2 и v3 помогло бы мне и, вероятно, другим.

@ shin- @ cpuguy83 Глядя на эту проблему год спустя, каковы _и_ аргументы в пользу отказа от добавления ее в версию 3?

Я не смог найти в этом ничего особенного, кроме «мы могли бы сделать это по-другому» (но на самом деле лучшего решения не было)
Есть ли технические ограничения? Или просто отсутствие пулл-реквеста?

В конце концов, мои файлы compose 2.1 все еще работают нормально.

Не только это, но и в журнале изменений написано, что «это было удалено, подробности см. В разделе« Как обновить »». Я смотрю на «как обновить», вы знаете, подробности о том, как обновить, и что там написано, это «см.« Расширение услуг »для подробностей». Я перехожу к «расширению служб», полагая, что наконец-то увижу способ расширить свои файлы, только чтобы увидеть «это было удалено, подробности см. В журнале изменений».

На данный момент это похоже на злую шутку, которую разыгрывает автор документации.

В конечном счете, формат «стека» здесь не контролируется и является частью Docker CLI.

Я лично не знаю, почему он был исключен из v3 ... Я также не думаю, что видел, чтобы кто-то действительно пытался добавить его.
Возможно, лучше всего поднять это в docker / cli ... возможно, даже просто PR с изменением документа высокого уровня, которое действует так, как если бы функция была там, чтобы ее можно было обсудить, и реализация может быть добавлена ​​после утверждения дизайна .

В основном, если кто-то этого хочет, устраивайте пиар. Я предлагаю изменить документ, чтобы убедиться, что вы не тратите кучу времени на случай, если он будет отклонен ... поскольку я снова не уверен, почему он был исключен из версии v3.

То же, что и выше. Ожидая решения этой проблемы, прежде чем снова использовать docker-compose.

+1, пожалуйста, исправьте это, у нас есть файлы компоновки на основе расширений, и из-за этого мы не можем использовать компоновку для роя.

+1 за расширенную функцию

Есть новости по этому поводу?

Все еще жду этого

То же самое. Все еще жду.

Есть обновления?

Была ли когда-либо указана причина, почему его убрали?

В пн, 5 августа 2019 г., 11:10 Джайкишан, [email protected] написал:

Есть обновления?

-
Вы получили это, потому что прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/moby/moby/issues/31101?email_source=notifications&email_token=ABOE6GA4CXY6ESMZMTDSFGDQC74CZA5CNFSM4DANZGS2YY3PNVWWK3TUL52HS4DFVREXG43V2HS4DFVREXG43V2HS4DFVREXG43VWWK3TUL52HS4DFVREXG43V2
или отключить поток
https://github.com/notifications/unsubscribe-auth/ABOE6GCEFFJ3SOLDWRWX2IDQC74CZANCNFSM4DANZGSQ
.

Есть обновления?

так .. это почти 3 года ...
но я все еще надеюсь, что он приземлится: D

Должна быть какая-то альтернатива расширениям, если они не вернутся. Почему бы не разрешить абстрактные сервисы? Формат файла будет плоским, и все сервисные декларации будут в одном файле. Вы можете использовать абстрактные службы в сочетании с возможностью yaml добавлять псевдонимы для узла (через & ) повторно использовать эти псевдонимы с помощью оператора <<: .

Почему 3 года !! Кажется, вы работаете и сосредотачиваетесь на вещах, которые никого не интересуют

какие-нибудь обновления по этому поводу?

Это жалко. Terraform использует композицию - так что это выполнимо, почему compose не может следовать этой хорошей дизайнерской практике ?!
Состав модулей Terraform
Лучшие практики Terraform

"жалко", приятно.

@ Cristian-Malinescu Давай, реализуй, пожалуйста.
Это бесплатное программное обеспечение с открытым исходным кодом.

Вместо того, чтобы жаловаться, как все в этом чате.
На самом деле это не добавляет здесь никакой ценности.
Как было сказано несколько раз, пока никто не хотел реализовывать это,
так что это просто проблема, которую должен исправить кто-то другой k, спасибо.

@luckydonald Спасибо, что оттолкнул @ Cristian-Malinescu простым / пассивно-агрессивным ответом, это как всегда не помогает. @ Cristian-Malinescu Это выполнимо, так как это уже было сделано ранее, но удалено, должна (я надеюсь) быть причина. Есть ли кто-нибудь в этой теме на самом деле в команде docker-compose, чтобы он / она мог пролить свет на иметь значение?

Обмотал тему и упомянул использование поддерживаемой функциональности YAML.

Думаю, этот пример может помочь.

@nomasprime спасибо за эту находку! Я выбирал между v2 и v3 для своего проекта, и это разрешило большую дилемму в этой теме. Удивлен, что эти альтернативные решения не упоминаются в официальных документах для функции расширения услуг.

Хорошо, звучит как хорошая возможность использовать ссылку Request docs changes на правой панели навигации на странице документов.

@nomasprime Да, эта идея уже

Если бы это можно было сочетать с механизмом загрузки файлов для других файлов yml, это все, что действительно нужно, чтобы иметь всю старую функциональность depends .

См. Выше, например https://github.com/moby/moby/issues/31101#issuecomment -413323610

Это было бы не очень _читабельно_, но, по крайней мере, _ возможно_.

@nomasprime спасибо за эту находку! Я выбирал между v2 и v3 для своего проекта, и это разрешило большую дилемму в этой теме.

@arseniybanayev В статье на medium говорится только о v3, но более новые версии v2 также поддерживают якоря и поля расширения . В моем случае я выбираю v2 (точнее 2.4), потому что я использую docker-compose а не swarm (и v3 не поддерживает некоторые функции v2, такие как ограничение памяти контейнера )

и v3 не поддерживает некоторые функции v2, такие как ограничение памяти контейнера

v3 поддерживает ограничение памяти, но поле находится под deploy -> resources -> limits https://docs.docker.com/compose/compose-file/#resources

@thaJeztah Я имею в виду, для docker-compose (потому что я не использую swarm в проекте, о котором упоминал в своем предыдущем комментарии). Развертывание IIRC предназначено только для роя, не так ли?

Есть ли смысл сделать отдельный конфиг для роя и локального? Похоже, эти двое противоречат друг другу. Понятно, что Docker хотел бы, чтобы использование роя увеличилось, но многие люди используют compose только для локальной разработки.

Я, например, никогда не использовал рой и запуск контейнеров в продакшене с ECS, k8s или GAE.

Большинство параметров должны быть переведены / использованы как для служб swarm / kubernetes, так и для контейнеров, развернутых через compose. Мне нужно было бы проверить, почему ограничения memory не применяются для docker-compose

по-прежнему отсутствует функция extends, но для моего основного варианта использования я переключился на несколько файлов для компоновки докеров через COMPOSE_FILE env. Я использую его в основном для использования одного и того же базового docker-compose.yml для dev и prod с разными паролями или конфигурацией.

пример:

  • на dev: export COMPOSE_FILE= docker-compose.yml` # по умолчанию
  • по продукту: export COMPOSE_FILE= docker-compose. yml: docker-compose.prod.yml `# использует оба файла yaml

В docker-compose.prod.yml я просто перезаписываю env vars паролями prod.

Эта установка проста, и мне не нужно всегда добавлять несколько "-f" к команде docker-compose . Мне просто нужно установить переменную COMPOSE_FILE env по-разному на компьютере разработчика и на сервере, и git игнорирует файл docker-compose.prod.yml.

Все еще жду :)

Я использовал это как способ расширить:

docker-compose \
  -f ./docker/base.yml \
  -f ./docker/extended.yml \
  up

Но расширение в файле было бы лучше, нет необходимости в дополнительном сценарии bash.

Я также использовал это для динамического расширения из сценария bash:

extended_docker_compose="
  version: '3.5'
  services:
    my-service:
      restart: always
"

echo "$extended_docker_compose" | docker-compose \
  -f ./docker/base.yml \
  -f /dev/stdin \
  up

@ dave-dm, это просто старые переопределения!

Я считаю, что это потенциальный допустимый вариант использования расширений

https://github.com/NerdsvilleCEO/devtools/blob/master/doctl/docker-compose.yml#L10

У меня есть оболочка docker-compose которую я использую для env сервисов https://github.com/nowakowskir/docker-compose-wrapper

РЕДАКТИРОВАТЬ: Другой возможный вариант использования - у кого-то есть стек LAMP / LEMP, и они хотят расширить эти службы для использования с определенной службой, такой как wordpress

Все еще ждем с 2017 года, исследуя альтернативы docker compose.

@nomasprime Да, эта идея уже

Если бы это можно было сочетать с механизмом загрузки файлов для других файлов yml, это все, что действительно нужно, чтобы иметь всю старую функциональность depends .

См. Выше, например, # 31101 (комментарий)

Это было бы не очень _читабельно_, но, по крайней мере, _ возможно_.

@luckydonald, спасибо, что указали. Странно, что нет встроенной функции включения YAML , безусловно, решило бы множество проблем.

Похоже, было бы довольно легко реализовать стороннее решение, хотя не знаю, почему это не было перенесено в v3 🤷‍♂

Небольшое напоминание, что эта функция понравится многим :)

В чем причина того, что его не портируют на v3, кстати?

Я забыл, но есть ли настоящая причина, по которой его забрали?

В среду, 6 мая 2020 г., 23:14 Жюльен Марешал, [email protected] написал:

Небольшое напоминание, что эта функция понравится многим :)

-
Вы получили это, потому что прокомментировали.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/moby/moby/issues/31101#issuecomment-624919070 или
отказаться от подписки
https://github.com/notifications/unsubscribe-auth/ABOE6GGDIVGATP734YJA4UTRQHOLJANCNFSM4DANZGSQ
.

Якоря yaml обрабатывают этот вариант использования немного неудобно по сравнению с extend . На мой взгляд, его сила во многом проистекает из рекурсивного слияния элементов. Якоря дадут вам примерно 75% пути - они не объединяют yaml рекурсивно; все ваше слияние происходит на верхнем уровне. Ссылка на шаблон привязанной службы и последующее переопределение блока environment приведет к перезаписи блока среды привязанной службы вместо слияния. Вам нужно будет привязать и ссылаться на каждый словарь в рекурсивном дереве словарей, чтобы соответствовать поведению ключевого слова extend .

Пример:

# anchors for the service, environment, deploy, and deploy.placement blocks
# you'll need an anchor for every dict that you want to merge into
x-common-app: &common-app
  image: app:1.0
  environment: &common-app-environment
    common_option: a
    overwrite_option: b
  deploy: &common-app-deploy
    max-replicas-per-host: 3
    placement: &common-app-deploy-placement
      constraints:
        - 'node.labels.app_host==true'

services:
  myapp: << *common-app
    environment: << *common-app-environment
      foo: bar
      baz: xyzzy
      overwrite_option: quz
    deploy: << *common-app-deploy
      replicas: 15
      placement: << *common-app-deploy-placement
        preferences:
          - spread: node.labels.region

# The above yields the following:
services:
  myapp:
    image: app:1.0
    environment:
      common_option: a
      overwrite_option: quz
      foo: bar
      baz: xyzzy
    deploy:
      replicas: 15
      max-replicas-per-host: 3
      placement:
        constraints:
          - 'node.labels.app_host==true'
        preferences:
          - spread: node.labels.region

В этом примере это может выглядеть не так раздражающе, но становится раздражающим и менее читаемым, если вы создаете несколько (10+) сервисов из одного блока расширения.

На мой взгляд, идеальный сценарий - это комбинация подхода привязки yaml и подхода extend - разрешить extend ing только из блока поля расширения с префиксом x- верхнего уровня, с более умные характеристики слияния.

В моей организации мы обнаружили, что якоря yaml немного синтаксически небрежны, поэтому мы в основном повторно реализовали функцию extend во внешнем скрипте Python. Это работает для нас, но это неубедительный способ с чем-то иметь дело. Точно так же нам пришлось создать наши собственные внешние инструменты для удаления depends_on из стеков v3 / Swarm.

В последнее время я много работал с gitlab CI YAML. У него есть именно эти функции, которые ооочень хороши для создания удобочитаемых и управляемых шаблонов и окончательных конфигураций:

  • Вы можете включить другие файлы YAML (подходит для шаблонов)
  • Вы можете расширять (даже по проектам / используя удаленные ресурсы через https). Расширенная документация точно описывает, что @ a-abella описывает для формата compose.
  • Вы также можете «спрятаться», чтобы вас не сочли настоящим. В формате compose это x- , в gitlab CI это начальное . .

Это точный набор функций, которые делают эти файлы переносимыми.

Я пришел к этой проблеме из документации докеров, в моем случае я хотел создать шаблон для моей установки docker-compose , и в качестве «обходного пути» я последовал приведенному выше совету и решил поискать существующую программу шаблонов. Я не верну те наши часы, поэтому я подробно расскажу о том, что я нашел здесь, независимо от каких-либо обсуждений этого фактического запроса функции, однако, возможно, участники почувствуют использование системы шаблонов на основе YAML для создать файл компоновки, а не интегрировать эту функцию в сам docker-compose может быть более подходящим с точки зрения инкапсуляции и выбора правильного инструмента для работы.

Для некоторого контекста я использую базовый обратный прокси-сервер с Let's Encrypt и несколькими контейнерами приложений (на данный момент Nextcloud, один для меня и несколько отдельных для друзей) - в этом случае я хотел создать шаблон контейнеров Nextcloud, чтобы что я избегаю ошибок и дублирования нажатий клавиш для очень похожих настроек. Я пробовал следующие пакеты:

ytt кажется очень всеобъемлющим и единственным вариантом использования YAML изначально. Он казался мощным и подходящим инструментом для работы, и он использует Starlark, надмножество Python, непосредственно внутри файла YAML для выполнения обработки. Однако вскоре шаблон стал очень беспорядочным, и засорение фрагментов кода и фрагментов YAML, а также смешение типов данных Python, таких как словари и массивы, и фрагменты YAML (которые, похоже, обрабатываются как текст, немного похоже на использование механизм шаблонов HTML, который выводит теги в виде строк) в конечном итоге приводит к слишком большому количеству ошибок и слишком беспорядку в файле. Dhall также кажется очень всеобъемлющим и использует уникальный родной язык, который можно выводить в различные форматы; Он больше похож на язык метапрограммирования, чем на систему шаблонов, однако, учитывая, что синтаксис является функциональным и довольно строго типизированным, он быстро стал более сложным, чем того стоило простой шаблон для неструктурированного YAML. Поскольку это немного похоже на смесь JSON и Haskell, потребовалось слишком много размышлений, чтобы проработать то, что мне нужно было сделать в языке.

Интересно, что что-то, что было сложно как с Dhall, так и с ytt, заключалось в использовании параметризованных имен полей, в противном случае оба работали бы достаточно хорошо, но мне нужно, чтобы имя моего экземпляра отображалось в именах служб и именах томов, и в обоих из них достигается это было несколько уродливо; использовать аргументы для значений в хэше легко, но использование этих аргументов в именах ключей было беспорядочным, или я не мог найти, как это сделать аккуратно, плюс Dhall обеспечивает безопасность типов, и это просто противоречит этой концепции. С Jsonnet это было просто - заключить выражение в квадратные скобки.

CUE и Jsonnet ориентированы на JSON, однако запустить их через конвертер совсем несложно, и, опять же, похоже, что, как и Dhall, CUE имеет множество мощных функций и был рожден из-за недостатков Jsonnet, но частично в документации. стало очевидно, что это уже излишество; возможно, имея гораздо больше времени, чтобы изучить его должным образом, это был бы лучший вариант, но кажется, что CUE больше ориентирован на проверку и схемы, чем на простую работу с шаблоном, поэтому я быстро перешел на Jsonnet и довольно быстро закончил работу.

Наконец, только после того, как я закончил все это, я понял, что все время, пока я сравнивал эти инструменты с простотой тегов Liquid или аналогичных HTML-шаблонов, я мог бы просто использовать Liquid в первую очередь. Я использовал его только в контексте сайта Jekyll, поэтому он просто никогда не возникал у меня для получения автономного пакета, однако с базовым циклом и списками, а также с возможностью оценивать выражения прямо в текст на месте, это, вероятно, был намного лучше для работы; Jsonify, вероятно, превосходит JSON, но Liquid может работать в чистом YAML, поэтому файл снова становится более читабельным.

+1 docker-compose был одним из вдохновителей индивидуального решения, которое я реализовал на работе, так как этот билет был создан для поддержки миграции большого количества тестовых окружений на k8s. Я очень осторожно избегал наворотов, но довольно быстро оправдал аналогичную особенность. Философская дискуссия (композиция против наследования и т. Д.) Кажется мне отвлечением от здравого смысла (с учетом преимуществ задним числом - все еще не решена почти 3 года спустя). Очевидно, это требуется людям, которые могут продолжать использовать docker-compose.

+1: +1:

Раньше я активно использовал эту функцию для сред dev / test / ci , где я мог расширяться из файла компоновки в путях подкаталогов ./config/{dev,test,ci}/compose.yaml . У меня был бы .env с COMPOSE_ENV=dev , но разработчики могли бы переопределить, и, очевидно, я бы переопределил в ci .

Я шокирован тем, что отказался от этой функции и не заменил ее чем-то похожим. Может быть, просто позволим нам использовать jinja2 и делать то, что мы хотим. Я надеюсь, что Docker-Compose будет менее анти-DRY. : '(

Похоже, что extends поддерживается docker-compose начиная с версии 1.27 (https://github.com/docker/compose/pull/7588).

Один из вариантов использования, когда я активно использую эту функцию, - это версия изображений докеров для кода. Мои файлы docker dev и prod compose являются наследниками docker-images.yml, где указан только базовый сервис, и помеченная версия образа сервиса.

Не нашел простого обходного пути в v3.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги