(Я создаю новый выпуск для этого, поскольку старый накопил довольно много багажа.)
Должна существовать возможность передавать переменные среды в значение любой * записи конфигурации в docker-compose.yml
. Многие люди хотят это сделать, это хорошо для портативности, и я доволен, что это не вызовет хаоса.
У меня есть некоторые расчеты.
Полезно иметь возможность указать, что переменная, которая _ должна_ присутствовать в среде, т.е. что Compose откажется запускаться, если это не так. Однако это будет неприятно, когда у вас их много, поэтому вы должны либо явно включить это, либо указать значение по умолчанию.
Реализация MVP не обязательно должна иметь какую-либо функцию, но должен быть четкий путь к реализации обеих обратно совместимым способом.
Есть веские аргументы в пользу внедрения установленного стандарта, если он не является тяжеловесным - наши требования к функциональности минимальны.
${VARIABLE}
- выводит пустую строку, если VARIABLE
не задано${VARIABLE-default}
- выводит default
если VARIABLE
не задано${VARIABLE?}
- выдает ошибки, если VARIABLE
не заданоhttps://github.com/docker/compose/pull/845 реализовал синтаксис ${VARIABLE:default}
стиле Bash, который похож на расширение параметров POSIX, но немного отличается.
Функция Python os.path.expandvars
реализует самый простой случай расширения параметра POSIX:
>>> from os.path import expandvars
>>> expandvars('${HOME}')
'/Users/aanand'
Однако у него как минимум 2 проблемы:
``
expandvars ('$ {UNSET}')
'$ {UNSET}'
``
- Неправильный синтаксис не вызывает ошибок - вместо этого он также не приводит к расширению:
``
expandvars ('$ {HOME')
"$ {HOME"
``
Пока что https://github.com/docker/compose/pull/845 - самое близкое из имеющихся у нас, но я принципиально опасаюсь реализации, которая полагается на регулярные выражения. Создание шаблонов - нетривиальная работа, и люди собираются вставлять в нее всевозможные поломанные вещи, поэтому нам нужно что-то надежное, строгое и ошибочное с полезными сообщениями. Два важных требования:
Вполне возможно, что уже существуют хорошие Python-реализации интерполяции переменных в стиле Bash - в противном случае создание чего-то автономного было бы намного предпочтительнее, чем раздувание кодовой базы Compose.
* На самом деле, существуют ли какие-либо ключи конфигурации, для которых мы _не должны_ разрешать интерполяцию?
Как далеко вы хотите зайти с этими установленными стандартами 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 Некоторые примечания здесь:
из шаблона импорта 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)
- Разве нам не нужны фильтры? С помощью фильтра вы можете легко определить значение по умолчанию ({{value | default ("default")}})
- Неужели нам действительно нужно заботиться о пользователях, которые используют расширенные функции Jinja для завинчивания файла YAML? Таким же образом пользователь может вручную создать недопустимый файл YAML. Я думаю, мы должны упростить задачу - попытаться обработать данный шаблон Jinja и вернуть ошибку, если произошла ошибка или созданный YAML недействителен (так же, как вы делаете сейчас).
- Если вы не видите Jinja2 как решение - было бы здорово использовать хотя бы {{переменную}} в качестве синтаксиса.
- 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 }
- ошибкиНедостатки:
$$
вместо \$
.На самом деле это может быть замаскированным благословением: 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 выглядит многообещающе.
Сейчас отчаянно нужен механизм для поддержки переменных по умолчанию, так как существующие ограничения вынуждают нас использовать сценарии оболочки для помощи при компоновке докеров. Мне нужны такие вещи, как 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
Самый полезный комментарий
Мой вариант использования - разрешить
$PWD
вvolumes
, чтобы каждый разработчик в команде мог клонировать репо куда угодно, и пути по-прежнему монтируются правильно.