Как упростить создание файлов Docker с помощью привязок и расширений YAML
Docker Compose позволяет управлять несколькими контейнерами Docker и связанными с ними ресурсами, такими как тома и сети. Вы пишете декларативные файлы YAML, которые Compose использует для создания стека контейнеров.
Ваши файлы docker-compose.yml
могут повторяться, когда вы работаете со сложным стеком. Службы могут совместно использовать параметры конфигурации, что приводит к дублированию разделов файла. Последующие обновления могут привести к ошибкам, если вы забудете обновить каждый экземпляр раздела.
Поскольку файлы Compose представляют собой обычные файлы YAML, вы можете воспользоваться встроенными функциями YAML для модульного разделения определений стека. Анкоры, псевдонимы и расширения позволяют абстрагировать разделы YAML в повторно используемые блоки. Вы можете добавить ссылку на раздел в каждом месте, где это необходимо.
Что такое якорь?
Якоря YAML — это функция, которая позволяет вам идентифицировать элемент, а затем ссылаться на него в другом месте вашего файла. Якоря создаются с помощью знака &
. За знаком следует псевдоним. Вы можете использовать этот псевдоним позже для ссылки на значение, следующее за привязкой.
Вот как вы можете использовать привязку, чтобы избежать повторения политик перезапуска контейнера:
services: httpd: image: httpd:latest restart: &restartpolicy unless-stopped mysql: image: mysql:latest restart: *restartpolicy
На якорь ссылаются с помощью символа *
и его псевдонима. Вы должны убедиться, что между символами &
/*
и следующим псевдонимом нет пробела.
В этом примере показано, как можно повторно использовать однострочное значение с якорями. Изменение политики перезапуска стека теперь можно выполнить в одном месте, без редактирования служб по отдельности.
Многострочные якоря
Якоря могут иметь многострочные значения. Вы создаете их, используя тот же синтаксис, что и однострочный якорь. Это полезно, когда вам нужно предоставить набор сведений о конфигурации для нескольких служб.
services: first: image: my-image:latest environment: &env - CONFIG_KEY - EXAMPLE_KEY - DEMO_VAR second: image: another-image:latest environment: *env
Служба second
теперь будет получать те же переменные среды, что и first
. Нам не пришлось повторять список переменных окружения, что сделало его более удобным для сопровождения в будущем.
Расширение значений привязки
Приведенный выше пример среды берет значение якоря и использует его как есть. Вы часто захотите расширить привязку, чтобы добавить дополнительные значения. Вы можете сделать это с помощью альтернативного синтаксиса.
Измените службу второй
следующим образом:
services: second: image: another-image:latest environment: <<: *env - AN_EXTRA_KEY - SECOND_SPECIFIC_KEY
Теперь служба извлекает базовую конфигурацию среды из привязки env
. Затем в список окружения добавляются дополнительные ключи. Вы также можете переопределить существующие ключи, определенные привязкой.
Использование полей расширения
Другой подход к модуляризации — поля расширения. Это специальные фрагменты YAML верхнего уровня, которые Docker будет игнорировать.
Docker обычно пытается интерпретировать любой узел в корне файла Compose. Парсер будет игнорировать поля расширения с префиксом x-
. Вы можете использовать эти поля для инкапсуляции общей конфигурации для дальнейшего использования. Объедините поля расширения с якорями, чтобы абстрагировать разделы от определений ваших услуг.
x-env: &env environment: - CONFIG_KEY - EXAMPLE_KEY services: first: <<: *env image: my-image:latest second: <<: *env image: another-image:latest
Этот файл Compose является дальнейшим усовершенствованием примера, показанного выше. Переменные среды больше не принадлежат ни одной из служб. Они были полностью вынесены в поле расширения x-env
.
Это определяет новый узел, который содержит поле environment
. Используется привязка YAML (&env
), поэтому обе службы могут ссылаться на значение поля расширения.
Компонуемость
Использование этих функций позволяет разбивать файлы Compose на автономные фрагменты. Это поможет вам избежать чрезмерно повторяющихся определений служб. Все, что является общим для более чем одной службы, должно быть поднято в поле расширения.
Помимо облегчения сопровождения, эта практика сообщает о ваших намерениях другим соавторам. Понятно, что любые поля расширения верхнего уровня содержат общие поля. Они не привязаны к какому-либо конкретному сервису и могут свободно использоваться повторно.
Якоря и поля расширений позволяют составлять определения службы из повторно используемых блоков YAML. Сохраняя каждое поле небольшим, ваши службы могут смешивать и сопоставлять разделы конфигурации из доступных якорей. Поддержание ваших файлов Compose должно стать менее рутинной задачей.
Другие подходы к модульности
Помимо якорей и расширений, не забывайте, что вы всегда можете разделить свои определения Compose на несколько файлов Compose. Это может быть необходимо, когда у вас больше, чем несколько отдельных сервисов.
Использование нескольких файлов Compose позволяет выделить каждой службе отдельный файл. Вы также можете создавать файлы переопределения, в которых значения узла заменяются или расширяются. Compose объединит все файлы вместе, чтобы создать окончательную конфигурацию среды выполнения.
service.yml
services: service: image: my-image:latest
service-dev.yml
services: service: environment: - DEV_MODE=true
В этом примере применение обоих файлов Compose приведет к созданию одной службы, my-image:latest
, с установленной переменной среды DEV_MODE
. Чтобы использовать несколько файлов с Compose CLI, передайте флаг -f
:
docker-compose -f service.yml -f service-dev.yml up -d
Файлы объединяются в указанном порядке.
Краткое содержание
Файлы Docker Compose могут стать громоздкими и повторяющимися. Если вы тратите время на копирование значений, рассмотрите возможность абстрагирования разделов ваших сервисов в выделенные блоки YAML.
Такие функции, как привязки и расширения, облегчают сопровождение и упрощают разработку. Не каждый файл Compose принесет пользу — некоторые сервисы могут иметь мало общего друг с другом, поэтому перед началом работы оцените свой конкретный стек.