Compose: Интерполировать переменные среды в docker-compose.yml

Созданный на 30 апр. 2015  ·  109Комментарии  ·  Источник: docker/compose

(Я создаю новый выпуск для этого, поскольку старый накопил довольно много багажа.)

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

У меня есть некоторые расчеты.

Обязательные переменные и необязательные значения по умолчанию

Полезно иметь возможность указать, что переменная, которая _ должна_ присутствовать в среде, т.е. что Compose откажется запускаться, если это не так. Однако это будет неприятно, когда у вас их много, поэтому вы должны либо явно включить это, либо указать значение по умолчанию.

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

Синтаксис

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

  • Расширение параметров POSIX в порядке. В нем слишком много функций, но мы могли бы реализовать их подмножество:

    • ${VARIABLE} - выводит пустую строку, если VARIABLE не задано

    • ${VARIABLE-default} - выводит default если VARIABLE не задано

    • ${VARIABLE?} - выдает ошибки, если VARIABLE не задано

https://github.com/docker/compose/pull/845 реализовал синтаксис ${VARIABLE:default} стиле Bash, который похож на расширение параметров POSIX, но немного отличается.

  • Синтаксис формата Python было бы тривиально реализовать, но он привязан к языку Python и имеет слишком много функций.

Реализация

Функция Python os.path.expandvars реализует самый простой случай расширения параметра POSIX:

>>> from os.path import expandvars
>>> expandvars('${HOME}')
'/Users/aanand'

Однако у него как минимум 2 проблемы:

  1. Неустановленная переменная не расширяется до пустой строки - вместо этого она не приводит к расширению:

``

expandvars ('$ {UNSET}')
'$ {UNSET}'
``

  1. Неправильный синтаксис не вызывает ошибок - вместо этого он также не приводит к расширению:

``

expandvars ('$ {HOME')
"$ {HOME"
``

Пока что https://github.com/docker/compose/pull/845 - самое близкое из имеющихся у нас, но я принципиально опасаюсь реализации, которая полагается на регулярные выражения. Создание шаблонов - нетривиальная работа, и люди собираются вставлять в нее всевозможные поломанные вещи, поэтому нам нужно что-то надежное, строгое и ошибочное с полезными сообщениями. Два важных требования:

  • Если кто-то вставит что-то неправильно, Compose не запустится.
  • Можно экранировать любой из специальных символов, используемых в синтаксисе шаблона.

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

* На самом деле, существуют ли какие-либо ключи конфигурации, для которых мы _не должны_ разрешать интерполяцию?

kinenhancement kinfeature

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

Мой вариант использования - разрешить $PWD в volumes , чтобы каждый разработчик в команде мог клонировать репо куда угодно, и пути по-прежнему монтируются правильно.

elasticsearch:
  image: zinvoice/elasticsearch
  volumes:
    - $PWD:/app

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

Как далеко вы хотите зайти с этими установленными стандартами UNIX? (FWIW, это не стандарт де-факто, это настоящий стандарт.)

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

@kojiromike Хм, так что расширение параметров POSIX - это на самом деле то, что я собирался, но, читая документы, похоже, я неправильно запомнил синтаксис / семантику.

Изменить: я обновил свои мысли о синтаксисе в описании.

Я слежу за старой веткой, и мы срочно хотели иметь эту функцию. В конце концов, боль была слишком большой, и мы создали скрипт bahs препроцессора yaml для замены переменных в стиле POSIX. он работал нормально, но в конце концов мы перестали его использовать, потому что у него была одна проблема. Вам нужно сначала запустить препроцессор и установить все параметры, прежде чем вы получите окончательное решение. Теперь мы используем функцию docker yaml extends. Потому что это позволяет нам проверить фактическую конфигурацию и просто выполнить ее на цели. Мы лучше знаем, что будет дальше.

Несмотря на то, что я был сторонником передаваемых переменных docker-compose, сейчас я не так уверен.

В качестве идеального решения я бы предпочел, чтобы docker extends выполнен правильно. В некотором смысле это было бы решение, подходящее обоим. Так что же не работает в docker extends? По сути, это тот факт, что вы должны записывать все записи в унаследованный файл. Это не слияние, при котором вы вводите только то, что хотите переопределить.

Посмотрите на реальный пример и насколько он подробный. Важны только две строчки.

#Common 
elasticsearch:
  image: zinvoice/elasticsearch
  hostname: elasticsearch
  restart: always
  dns: 172.17.42.1
  ports:
    - "9200:9200"
  volumes:
    - /etc/localtime:/etc/localtime:ro
    - /etc/timezone:/etc/timezone:ro
    - /data/elasticsearch:/opt/elasticsearch/data/elasticsearch

logstash:
  image: zinvoice/logstash
  hostname: logstash
  dns: 172.17.42.1
  restart: always
  ports:
    - "5000:5000"
  volumes:
    - /etc/localtime:/etc/localtime:ro
    - /etc/timezone:/etc/timezone:ro

kibana:
  image: zinvoice/kibana
  hostname: kibana
  dns: 172.17.42.1
  restart: always
  ports:
    - "5601:5601"
  volumes:
    - /etc/localtime:/etc/localtime:ro
    - /etc/timezone:/etc/timezone:ro

logspout:
  image: zinvoice/logspout
  hostname: logspout
  command: logstash://logstash.docker:5000
  restart: always
  dns: 172.17.42.1
  ports:
    - "8003:8000"
  volumes:
    - /var/run/docker.sock:/tmp/docker.sock

doorman:
  image: zinvoice/doorman
  hostname: doorman
  restart:  always
  dns: 172.17.42.1
  ports:
    - "8085:8085"
# inherited
elasticsearch:
  extends:
    file: ../common.yml
    service: elasticsearch

logstash:
  extends:
    file: ../common.yml
    service: logstash

kibana:
  extends:
    file: ../common.yml
    service: kibana

logspout:
  extends:
    file: ../common.yml
    service: logspout

doorman:
  environment:
    - DOORMAN_GITHUB_APPID=xxxxxxxx
    - DOORMAN_GITHUB_APPSECRET=xxxxxx
  links:
    - nginxtrusted
  extends:
    file: ../common.yml
    service: doorman

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

Взгляните на YAML «привязки узлов» и YAML «слияние файлов», это может быть идеальным решением.

К вашему сведению: это обсуждение продолжается сейчас на # 1380

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

Конечно! Я просто хотел подчеркнуть, что это может быть простой и элегантной альтернативой.
Если compose extends дает вам половину пути к передаче переменных, тогда улучшенная compose-extends сделает передачу переменных устаревшей. Меньшее количество понятий облегчает пользователю понимание.

Мой вариант использования - разрешить $PWD в volumes , чтобы каждый разработчик в команде мог клонировать репо куда угодно, и пути по-прежнему монтируются правильно.

elasticsearch:
  image: zinvoice/elasticsearch
  volumes:
    - $PWD:/app

@mattes Я считаю, что это уже поддерживается, я думаю, что .:/app поддерживается

@aanand В качестве PoC я сделал грязный взлом POSIX PE на Python . По субботам.

@kojiromike Отлично выглядит. Дайте мне знать, если вы планируете продолжить.

@aan, и я собираюсь это сделать, но прямо сейчас в нем определенно есть несколько ошибок (и я думаю, что, возможно, было плохой идеей использовать shlex ). Конечно, приветствуются сообщения об ошибках и PR.

@dnephin как насчет $HOME / ~ ?

@nafg Оба они поддерживаются для пути к хосту тома

@dnephin интересно, b / c как-то у меня оказался каталог с именем '$ HOME' ...

@aanand Как и предложение "$ { VARIABLE: default }", с global_extends (или "import") это могло бы стать довольно мощным.

В: Это позволит указать номер порта, доступного для хоста? например - "$ {WEB_ PORT: 80 }: 80"?
Сценарий использования - возможность легко запускать несколько экземпляров приложения на одном компьютере / кластере, обычно прослушивая разные порты или назначая разные локальные доменные имена.

Да, ты сможешь это сделать.

Я хочу использовать vars в объемах вместе с docker-compose scale my_app=3 . У меня есть docker-compose.yml

server:
  image: alexanderilyin/docker-teamcity-server
  ports:
   - "8111:8111"
  volumes:
    - .TeamCity:/root/.BuildServer
  links:
   - mysql
mysql:
  image: alexanderilyin/docker-mysql
  volumes:
    - .MySQL:/var/lib/mysql
  environment:
    MYSQL_DATABASE: teamcity
    MYSQL_USER: teamcity
    MYSQL_PASSWORD: teamcity
    MYSQL_ALLOW_EMPTY_PASSWORD: yes
agent:
  image: alexanderilyin/docker-teamcity-agent
  links:
   - server

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

agent:
  image: alexanderilyin/docker-teamcity-agent
  volumes:
    - .agent_{$AGENT_INSTANCE_ID}:/opt/buildAgent
  links:
   - server

Я надеюсь, что можно будет также интерполировать переменные как часть имени изображения
Мы используем https://github.com/openshift/source-to-image для создания локального контейнера на CI для каждой ветки, а затем запускаем на нем тесты с помощью docker-compose.
Выполнение тестов с динамическим изображением довольно сложно с docker-compose и требует ручного рендеринга шаблона ..: -1:

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

@andrerom не подписывайтесь. Согласно документам, которые контролируют следующий Sets the project name, which is prepended to the name of every container started by Compose пока мы пытаемся вместо этого установить свойство изображения:

web:
  image: <I_AM_DYNAMIC>

ах, моя ошибка.

Думал, ты имел в виду

<I_AM_DYNAMIC>:
  image: nginx

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

Дополнительный вариант использования _ (который может быть тем, что имеет в виду @ Maxim-Filimonov) _: возможность переопределить, какой тег использовать для изображения, поэтому вы можете использовать: latest по умолчанию, но изменить, чтобы легко протестировать что-то еще без изменения yml file _ (необходим в основном для CI) _.

@andrerom , это как раз наш вариант использования: +1:

Будет ли это работать и для таких вещей, как ??

web:
  environment:
    - FOO=${whoami}

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

В этом конкретном случае переменная окружения $USER , вероятно, даст вам то же самое.

@aanand Почему бы не использовать какой-либо из существующих шаблонизаторов? Jinja2 есть и отлично работает.

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

В качестве альтернативы мы можем использовать якоря и ссылки YAML https://gist.github.com/bowsersenior/979804

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

+1 за Jinja2: он определенно подходит для шаблона, и ансибл использует его для
именно этот вариант использования (шаблон в файлах yml)

Во вторник, 26 мая 2015 г., в 13:25, tonnzor [email protected] написал:

@aanand https://github.com/aanand Почему бы не использовать любой из существующих шаблонов
двигатели, которые уже есть? Jinja2 есть и отлично работает.

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

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/docker/compose/issues/1377#issuecomment -105493447.

Jinja2 делает намного больше, чем нам нужно:

  • условные
  • зацикливание
  • расширение / наследование
  • Комментарии
  • фильтры

Мы не добавляем ничего из этого в Compose. Если Jinja2 можно настроить только на интерполяцию переменных, он может быть кандидатом.

На самом деле цикл может быть интересным.

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

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

Фильтры отлично подходят для работы с существующими переменными.

26 мая 2015 г., в 13:56, Аананд Прасад [email protected]
написал:

Jinja2 делает намного больше, чем нам нужно:

  • условные
  • зацикливание
  • расширение / наследование
  • Комментарии
  • фильтры

Мы не добавляем ничего из этого в Compose. Если Jinja2 можно настроить
чтобы просто интерполировать переменные, тогда это может быть кандидат.

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/docker/compose/issues/1377#issuecomment -105498909.

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

@aanand Некоторые примечания здесь:

  1. Jinja2 надежен, и на предварительную обработку YAML уходит несколько минут:

из шаблона импорта jinja2
template = Template ('Привет, {{имя}}!')
template.render (name = "Aanand")
Привет, Ананд!

Если вы хотите большей безопасности - вы можете использовать неизменяемую песочницу:

из jinja2.sandbox import ImmutableSandboxedEnvironment
env = ImmutableSandboxedEnvironment ()
template = env.from_string ('Привет, {{имя}}!')
template.render (name = "Aanand")
Привет, Ананд!

В нашем случае это будет:

импорт ОС
из jinja2.sandbox import ImmutableSandboxedEnvironment
env = ImmutableSandboxedEnvironment ()
template = env.from_string ('Привет, {{имя}}!')
template.render (** os.environ)

  1. Разве нам не нужны фильтры? С помощью фильтра вы можете легко определить значение по умолчанию ({{value | default ("default")}})
  2. Неужели нам действительно нужно заботиться о пользователях, которые используют расширенные функции Jinja для завинчивания файла YAML? Таким же образом пользователь может вручную создать недопустимый файл YAML. Я думаю, мы должны упростить задачу - попытаться обработать данный шаблон Jinja и вернуть ошибку, если произошла ошибка или созданный YAML недействителен (так же, как вы делаете сейчас).
  3. Если вы не видите Jinja2 как решение - было бы здорово использовать хотя бы {{переменную}} в качестве синтаксиса.
  4. Django использует регулярное выражение для анализа и создания шаблона. Он уже давно серийный и прекрасно с ним живет.

импорт ОС
импорт ре
template = "Здравствуйте, {{name}}!"
re.sub ("{{\ s _ ([a-zA-Z0-9 _] +?) \ s_}}", лямбда m: os.environ.get (m.group (1), ''), шаблон)

В любом случае - нам нужно, чтобы эта функция работала, какое бы решение мы ни приняли.

Я +1 за использование общего решения для создания шаблонов, если шаблоны рассматриваются. Например, http://mustache.github.io , который доступен на многих языках. Это всего лишь пример, другие движки шаблонов можно рассматривать как

@aan, и я полностью понимаю вашу точку зрения. Еще мне нравится простота и
лаконичность композиции dsl.

Может быть, это нужно сделать как внешний проект, скажем мета-композитор. Это
принимает compose.tpl.yml и variables.yml, создает docker-compose.yml
и поехали.
Как показал @tonnzor, это можно сделать с помощью крошечного фрагмента кода Python.

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

Во вторник, 26 мая 2015 г., в 16:52, Себастьян ван Стейн <
[email protected]> написал:

Я +1 использую решение для создания шаблонов _generic_, если шаблоны
считается. Например, http://mustache.github.io , который доступен во многих
языков. Это просто пример, другие движки шаблонов могут быть
считается одинаково

-
Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/docker/compose/issues/1377#issuecomment -105551631.

Хм… Итак, теперь предлагается использовать язык шаблонов внутри compose.yml (который является описательным языком для создания контейнеров Docker) для таких вещей, как command и entrypoint , которые уже принимают оба exec Значения стиля sh -c ? Это может сбивать с толку, так как после рендеринга шаблона результирующая команда оболочки все равно будет предположительно интерпретироваться, поэтому, если переменная расширилась до * она будет расширена glob. Экранирование последовательностей на том или ином языке становится сложным, когда у вас есть такое множество уровней провальной интерпретации.

@kojiromike Я не уверен, что нужен шаблонизатор, но если он будет использоваться! лучше использовать что-нибудь известное. Основной вопрос: должен docker-compose написать замену с нуля или использовать что-то существующее.

26 мая 2015 г., 11:02 Christoph Witzany [email protected]
написал:

@aan, и я полностью понимаю вашу точку зрения. Еще мне нравится простота и
лаконичность композиции dsl.

Может быть, это нужно сделать как внешний проект, скажем мета-композитор. Это
принимает compose.tpl.yml и variables.yml, создает docker-compose.yml
и поехали.

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

Что было бы действительно полезно, так это если бы compose могла читать файл из stdin.
Это устранило бы необходимость в промежуточном файле.

Как показал @tonnzor, это можно сделать с помощью крошечного фрагмента кода Python.

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

Во вторник, 26 мая 2015 г., в 16:52, Себастьян ван Стейн <
[email protected]> написал:

Я +1 использую решение для создания шаблонов _generic_, если шаблоны
считается. Например, http://mustache.github.io , который доступен во многих
языков. Это просто пример, другие движки шаблонов могут быть
считается одинаково

Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/docker/compose/issues/1377#issuecomment -105551631.

Ответьте на это письмо напрямую или просмотрите его на GitHub
https://github.com/docker/compose/issues/1377#issuecomment -105554730. src = "
https://ci6.googleusercontent.com/proxy/iSBXyl7D8PwFM4p1mGPHCR7bQctunieGbhyGkvo0QIMIjmAYE3I0Mt96yl1fGrqcuOzxV4APP8ZRIw-5_qd6nzps9Mpr6jTAydCC4xs8JDgqm93aIbWvN1eMlxykrz7iwYooyAQdqL4RFJokeEbnBkZm5mhgKg=s0-d-e1-ft#https://github.com/notifications/beacon/AAGAUO8xqz29B2SUoG7QFPUy848_JJW9ks5oNIJlgaJpZM4EMysO.gif
">

+1 за чтение файла со стандартного ввода. У меня нет проблем с использованием внешнего шаблона, но было бы неплохо не иметь промежуточных файлов.

Это звучит как отличный первый шаг и общая черта многих инструментов cli. Давайте сделаем это

: +1:

Так например

envsubst compose.tmpl.yml | docker-compose -f - up -d

wfm. : +1:

Только что заметил, что docker / distribution обрабатывает переопределение значений в файле yml через переменные среды, но с использованием другого подхода https://github.com/docker/distribution/blob/master/docs/configuration.md#override -configuration-options

^^ @aanand

@thaJeztah , это сработает и для нас. Мы можем использовать переменные среды для переопределения команд, затем

DOCKER_COMPOSE_IMAGE_NAME='my_image:is_dynamic'

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

@aan, и этот подход тоже не очень

Просто наткнулся на https://github.com/kelseyhightower/confd, который может вас заинтересовать. Он использует http://golang.org/pkg/text/template/#pkg -overview

@olalonde, к сожалению, docker-compose написан на Python, поэтому Go-шаблоны работать не будут.

@aan и я +20 к вашему первоначальному предложению, с настройкой, чтобы можно было вводить даже изображения и особенно теги. Просто сделайте это, это избавит всех нас от множества оберток и ненужной обработки конфигурации;)

Я написал небольшой пакет Python, который мне в этом помогает. План состоит в том, чтобы туннелировать все команды в docker compose, чтобы вы могли использовать его эквивалентно.
Проверьте это на https://github.com/webcrofting/meta-compose/

meta-compose выглядит действительно красиво. Он должен быть интегрирован в docker-compose!

Большой +1 здесь - я не в восторге от предварительной обработки шаблонов, но получить переменные среды так или иначе было бы здорово. Расширение POSIX, вероятно, чище, чем Jinja2, но в любом случае это нормально.

Большой +1 отсюда тоже. Мой вариант использования больше связан с добавлением поддержки динамического рекламного идентификатора для контейнера kafka, который жизненно важен для производителей данных (которые могут быть другими контейнерами).

Я тоже в восторге от этой функции.

Расширение POSIX, вероятно, чище, чем Jinja2, но в любом случае это нормально.

Я думаю, что еще одним аргументом в пользу расширения POSIX является отсутствие логики. Jinja2 поддерживает некоторую степень условной логики / цикла (как и большинство движков шаблонов, даже тех, которые заявляют, что они «лишены логики»). По моему опыту, сочетание логики шаблонов и YAML довольно странно. Может ли кто-нибудь придумать вариант использования такой логики? Если нет, то, возможно, лучше прямо сейчас избегать поддержки.

Было бы неплохо получить четкий ответ от разработчиков по поводу этой функции. Читая разные выпуски и пиар, не понятно, действительно ли ты хочешь реализовать это или нет.

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

Спасибо !

Хорошо, я только что увидел https://github.com/docker/compose/pull/76. Думаю, ответ есть ...

Сделал несколько циклов по связанным вопросам / PR.

AFAIK, сообщество nginx отказалось принять какой-либо механизм шаблонов для файлов конфигурации, даже для простой замены переменных. Почему? Может быть, они все еще выбирают идеальный шаблонизатор: smile :. Результат? Боль (относительно)!

@hadim

Читая разные выпуски и пиар, не понятно, действительно ли ты хочешь реализовать это или нет.

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

спасибо @aanand !

Спасибо, @aanand.

+1 для меня. Мне нужно передать --dns = (адрес моста docker0), и мне нужно, чтобы он работал, если это когда-либо изменится в будущих версиях докера, поэтому переменная среды и / или оболочка идеально подходят. meta-compose не работает для меня, так как он должен поддерживать удаленный DOCKER_HOST и, например, через docker-swarm, а не только локально.

: +1: Было бы очень хорошо. В настоящее время я либо создаю файл .yml с помощью другого скрипта, либо просто не использую docker-compose вообще, а вручную докеры --link-ing.

:недурно:

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

Пара простых вариантов использования:

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

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

Что касается объединенного PR # 1488, меня особенно интересует передача файла конфигурации по конвейеру docker-compose . Я не могу понять, почему docker-compose не может быть получен из процесса узла.

var spawn = require('child_process').spawn;

var compose = spawn('docker-compose', ['--file' + '-' + 'up']);

compose.stdin.setEncoding = 'utf-8';

compose.stdout.on('data', function (data) {
    console.log('"docker-compose --file - up" stdout: "%s".', data);
});

compose.stderr.on('data', function (data) {
    console.log('"docker-compose --file - up" returned an error: "%s".', data);
});

compose.on('close', function (code) {
    if (code !== 0) {
        console.log('"docker-compose --file - up" existed with an erroneous code: "%s".', code);
    } else {
        console.log('"docker-compose --file - up" existed with code: "%s". SUCCESS!', code);
    }
});

compose.stdin.write("redis: {\"image\": \"redis\"}\n");
compose.stdin.end();

Любые примеры того, как передавать данные из Node.js?

Еще я обнаружил, что docker-compose 1.4.0-RC1 отправляет некоторые, казалось бы, нормальные сообщения, такие как Starting... или Attaching... на stderr вместо stdout .

@kadishmal Не могли бы вы открыть для них отдельные вопросы?

Другой вариант синтаксиса / реализации: шаблон строки Python, указанный в PEP 0292 и реализованный в string.Template .

Это очень похоже на расширение параметра POSIX:

  • $foo заменяется на значение foo
  • ${foo} заменяется на значение foo
  • $ , ${ , $} , ${} , ${foo , $ {foo} , ${ foo} , ${foo } - ошибки

Недостатки:

  • Нет значения по умолчанию или синтаксиса «обязательного значения». Тем не менее, позже мы сможем решить, хотим ли мы, чтобы их было достаточно, чтобы написать собственный код шаблона.
  • Сообщения об ошибках не предоставляют никакой машиночитаемой информации о том, где находится синтаксическая ошибка (то есть без выполнения сопоставления регулярных выражений в строке ошибки).
  • Синтаксис escape отличается от POSIX: $$ вместо \$ .

На самом деле это может быть замаскированным благословением: YAML не любит \$ и требует двойного выхода. Я не думаю, что совет людям набирать \\$ только для того, чтобы получить знак доллара, взлетит.

Я добавил реализацию в # 1765.

+1

Я не уверен, подходящее ли это место для этого, или мне следует сделать новый выпуск.

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

Вот что сейчас происходит, когда я пробую:

docker-compose.yml:

test:
    image: ubuntu
    environment:
        - FOO="from compose"

а затем запустите его с помощью команды env :

docker-compose run test env | grep FOO

дает FOO="from compose" , как и ожидалось. Но потом:

FOO="from shell" docker-compose run test env | grep FOO

также дает FOO="from compose" , но здесь я ожидал FOO="from shell" .

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

@fazy вы не учли, что команда env была выполнена в изолированном контейнере test в котором FOO from compose (просто так, как должно быть и как было настроено в файле docker-compose ). Но за пределами этого контейнера, если бы docker-compose процесс имел какую-то функцию печати для переменной среды, которую вы установили перед командой, он бы напечатал `` из оболочки '', потому что это значение для хоста (а также для процесс docker-compose ), на котором вы его запускаете. Возможно, вы ожидали, что в этом случае значение FOO будет from shell но лично я был бы очень удивлен, если бы это было так. (Надеюсь, несмотря на мой английский, вы меня поймете).

@smileart, спасибо, я понимаю, о чем вы говорите.

Однако контейнер test не изолирован полностью, он получает свою среду из docker-compose (или, по крайней мере, docker-compose может устанавливать переменные среды в запущенный контейнер), а docker-compose сам может видеть "внешнюю" переменную окружения.

Вы можете увидеть с этим docker-compose.yml:

test:
    image: ubuntu
    environment:
        - FOO

Затем команда:

FOO="from shell" docker-compose run test env | grep FOO

действительно дает результат "из оболочки".

Итак, мой вопрос о приоритете. Указав здесь только имя переменной, - FOO , я могу ввести переменную извне. Но если я укажу - FOO=something _and_ введите переменную извне, что должно иметь приоритет? IMHO переменная, указанная в командной строке, должна иметь приоритет над файлом конфигурации.

@fazy Ой, извините, я не пробовал FOO="from shell" docker-compose run test env | grep FOO без указания его значения в docker-compose.yml и я не знал, что он дает нам значение FOO хоста. Так что это не просто было бы для меня уже странно: smiley: Я думал, что установка переменной окружения до того, как docker-compose повлияет ТОЛЬКО на docker-compose и docker-compose ТОЛЬКО, не бросая ее контейнер. Теперь я понимаю, что вы имели в виду.

Я только что наткнулся на недостаток экранирования $ упомянутый в https://github.com/docker/compose/issues/1377#issuecomment -124571722. Сначала я сделал только FOO=ba$e затем FOO='ba$e' (забыв, что он взят "голый"), затем FOO=ba\$e , затем FOO=ba\\$e , затем я сдался и пошел документации, просто чтобы быть удивленным, обнаружив, что « $ - это escape-символ для $ ». Для меня это не было чем-то особенным "наименьшим удивлением".

Однако я не знаю, какое было бы хорошее решение.

@ ct-clearhaus Compose - не единственная программа, которая использует $ для экранирования $ . Вы также найдете это в make-файлах. Так что некоторым людям эта идиома хорошо знакома.

Мне нравится существующая реализация замены переменных . Однако я действительно мог бы использовать возможность установить значение по умолчанию в соответствии с исходным предложением @aanand . Я думаю, что синтаксис POSIX идеален:

${ENV-default}

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

PORT=8123 docker-compose up

Добавив это в мои docker-compose.yml :

web:
  ports:
    - "${PORT-8000}:5000"

Эта функция все еще в планах и в разработке?

Я попытался решить свою проблему с помощью расширений , но получилось довольно запутанно. Мне не только пришлось дублировать почти все мои docker-compose.yml только для того, чтобы изменить одну настройку, также нет возможности _изменить_ настройки открытого порта, вы можете только add to список открытых портов, который не идеален для меня.

Почему docker-compose не завершается с ошибкой, если не заданы переменные среды? Он просто регистрирует предупреждение и продолжает работу. Не было бы лучше просто вернуться и ошибка ...
WARNING: The FOO variable is not set. Defaulting to a blank string.

+1 для синтаксиса POSIX для объявления значений по умолчанию

Возможно, мне не хватает чего-то очевидного, но я хотел бы иметь возможность использовать переменные среды из env_file для установки значения переменной среды, например:

docker-compose.env:

DB_PASSWORD=test

docker-compose.yaml:

...
service:
    database:
        env_file:
            - ./docker-compose.env
        environment:
            - MYSQL_PASSWORD=${DB_PASSWORD}
    webserver:
        env_file:
            - ./docker-compose.env
        environment:
            - WORDPRESS_DB_PASSWORD=${DB_PASSWORD}

Можно ли это сделать другим способом? Я не хочу иметь файл шаблона yaml, который нужно передать через envsubst.

Почему бы просто не поместить это значение прямо в env_file так, как вы хотите?

2636 будет поддерживать файл env для значений по умолчанию

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

Сейчас отчаянно нужен механизм для поддержки переменных по умолчанию, так как существующие ограничения вынуждают нас использовать сценарии оболочки для помощи при компоновке докеров. Мне нужны такие вещи, как NODE_ENV=${NODE_ENV:-dev} для работы, и для удобства было бы неплохо иметь SOME_NUMBER=$((96*60)) для работы. Планируется ли это для следующей версии?

+1 для значений по умолчанию

+1 для значений по умолчанию. это становится для нас критически важным.

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

Если бы только я мог:

    user: $((id -u)):$((id -g))

это решит все мои проблемы

@mgor Похоже, вы могли бы просто передать его через envsubst ?

env $(cat docker-compose.env | xargs) envsubst < docker-compose.tmpl > docker-compose.yml

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

@OJFord @mgor Я не собирался перехватывать поток, но я создал пару инструментов CLI, чтобы иметь более чистый рабочий процесс; envset и slv .

envset development -- slv docker-compose.tpl > docker-compose.yml

envset загрузит переменные из файла env в текущий сеанс оболочки, slv заменяет шаблон с использованием переменных среды.

Я согласен с @OJFord, но это не то, что мне нужно ...
Позвольте мне уточнить: мы команда из 40 разработчиков, которые используют разные стеки docker-compose. Мы используем git для получения кода.

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

Я могу «сгенерировать базовый файл композитора», который игнорируется git и расширяется docker-compose.yml, но для его генерации мне нужно будет дать им Makefile или bashscript ... Придет день, когда «base docker file "потребуется изменение, и команда не будет знать, что им нужно будет повторно запустить генерацию.

То же самое для файла "env", это очень хорошо, но он не работает с "build", и мне нужно попросить мою команду сгенерировать этот файл.

На самом деле, если docker-compose может получать значения из bash (или любого другого решения, которое возвращает что-то еще, что переменная ENV) в файле yaml, решит множество потребностей.

Мой пример из моей предыдущей команды идеален: мне нужно получить идентификатор пользователя и gid, а значения thoses не устанавливаются переменными ENV. Поэтому мне нужно попросить мою команду записать свои идентификаторы в файл .env ... Это просто для меня и вас, не для всех.

Точнее: мне нужно предоставить файл для создания докеров, который не должен изменяться командой, потому что он находится в репозитории git.

Этот пул-реквест - простой пример, который мне подходит. Может ты поможешь мне стать лучше.

Я пробовал использовать окружение и пользовательские директивы из файла docker-compose.yml. Пока работает хорошо.

Там должно быть значение по умолчанию ... Очень полезно ... Разработчики и OPS используют либо журналы докеров, либо syslog ... Итак, им обычно приходится создавать LOG_FORMAT по умолчанию, показанный ниже ... Мы могли бы просто иметь значение по умолчанию и использовать его только при переключении на системный журнал ...

default:
  extends:
    file: base.yml
    service: base-${LOG_FORMAT:docker}
  labels:
    - "net.company.npmjs.datacenter=${DATA_CENTER}"
    - "net.company.npmjs.env=${ENV}"
    - "net.company.npmjs.hostname=${HOSTNAME}"
    - "net.company.npmjs.role=${NPMO_ROLE}"
    - "net.company.npmjs.log=${LOG_FORMAT}"

base-syslog:
  log_driver: syslog
  log_opt:
    tag: "{{.ImageName}}/{{.Name}}/{{.ID}}"

base-docker:
  log_driver: json-file
  log_opt:
    max-size: "128m"
    max-file: "4"

Когда это будет доступно? Я использую Compose 1.7.0, а этого до сих пор нет :(

Пожалуйста, укажите значения по умолчанию!

@marcellodesales : Возможно, вам удастся docker-compose.override.yml . Проверьте эту функцию.

Также +1 на env vars. В настоящее время это наша основная проблема с docker-compose.

Я бы настаивал на моем PR # 3367, чтобы иметь возможность получать определенные значения от хоста. :)

@pataquets Я не думаю, что хочу создать еще один файл переопределения ... наш файл base.yml , как показано выше, показывает все поддерживаемые вещи с точки зрения драйвера регистратора и т.д ... Я просто хочу переключить и имеют значения по умолчанию. Я думаю, что нам нужно поддерживать еще больше файлов yml. Но на всякий случай запомню.

+1

+1

+1

+1

Любое уведомление об использовании переменных среды в docker-compose?

+1

+1

К вашему сведению: переменные среды для docker-compose работают с версии 1.7.0. Вы также можете установить переменные по умолчанию для docker-compose в .env в том же каталоге, что и ваш корневой файл docker-compose.yml . Это не следует путать с envfiles движка докеров, это совсем другое дело.

Есть ли способ установить имя службы в качестве переменной?

Вместо того, чтобы писать это

services:
   site_db:
     image: mysql:5.7

Мы могли написать

services:
   ${CONTAINER_NAME}:
     image: mysql:5.7

Моя цель - сохранить одинаковые docker-compose.yml на нескольких сайтах и ​​изменить только файл .env . Прямо сейчас мне все еще нужно изменить имя контейнера, потому что я запускаю несколько приложений на одном хосте. И для ясности я бы хотел, чтобы у каждой службы было собственное название.

@LouWii вы можете использовать

services:
    site_db:
      container_name: "${CONTAINER_NAME}"
      image: mysql:5.7

или (формат композитного файла 2.1 и выше)

services:
    site_db:
      container_name: "${CONTAINER_NAME:-defaultname}"
      image: mysql:5.7

Но почему бы не указать имя проекта? Имя проекта _intended_ для этого, поскольку оно префиксов / пространств имен контейнеров, которые создаются для предотвращения конфликта с другими проектами на том же хосте. См. Https://docs.docker.com/compose/reference/envvars/#/composeprojectname

@thaJeztah Спасибо! Я все еще изучаю, как работают Docker и docker compose. Установка имени проекта кажется лучшим вариантом, это имеет смысл в моем использовании.

Есть ли способ написать сценарий в интерполированных фигурных скобках? Например, ${HOST_PORT + 1} .

Вы можете пропустить файл через Jinja или что-то в этом роде ...

24 января 2017 г., 5:36 Сэм А. Хорват-Хант [email protected]
написал:

Есть ли способ написать сценарий в интерполированных фигурных скобках? Например, $ {HOST_PORT

  • 1}.

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

Могу ли я сбежать от $ ?

environment:
   PATH: "$PATH:/home/appuser/.bundler/bin"

В настоящее время это приводит к интерполяции переменной PATH хоста, а не контейнера.

найден только один файл docker-compose.yml?
как я могу его добавить или изменить?
заранее спасибо

@logicminds, хотя я нигде не мог найти это задокументировано, я обнаружил, что $$ интерполируется в экранированный $ .

environment:
   PATH: "$$PATH:/home/appuser/.bundler/bin"

У @elquimista есть решение, которое я нашел полезным https://github.com/mhart/alpine-node/issues/48#issuecomment -430902787

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